我想用 libcurl 读取多个在线文件(尤其是使用 fopen.c 中定义的函数)。为此,我想使用多个线程,但每个文件只使用一个线程。我的代码对一个 URL 工作正常,但给出了段错误,或者对多个文件进行了核心转储。
这是我的代码:
void * extract_file(void * filename)
{
URL_FILE *handle;
int err;
CURL *curl = curl_easy_init();
if(curl == NULL) {
fprintf(stderr, "Error while initializing libcurl.\n");
exit(EXIT_FAILURE);
}
CURLcode curlcode = curl_easy_setopt(curl, CURLOPT_NOSIGNAL, true);
char *file = (char *) filename;
handle = url_fopen(file, "rb");
if(handle == NULL) {
fprintf(stderr, "Error while opening %s.\n", file);
exit(EXIT_FAILURE);
}
uint64_t n;
bool empty = true;
while(url_fread(&n, sizeof(uint64_t), 1, handle) != 0) {
empty = false;
sem_wait(&empty1);
pthread_mutex_lock(&mutex1);
push(&buffer1, n);
pthread_mutex_unlock(&mutex1);
sem_post(&full1);
}
err = url_fclose(handle);
if(err != 0) {
fprintf(stderr, "Error while closing %s.\n", file);
}
curl_easy_cleanup(curl);
debug_printf("Leaving extract_file.\n");
if(empty) {
fprintf(stderr, "%s is either empty or non-existing.\n", file);
exit(EXIT_FAILURE);
}
pthread_exit(NULL);
}
注意:我删除了一些不重要的代码细节。
每个“阅读器”线程使用通常的 pthread_create 启动此函数。 所以我有两个问题: 1)为什么我不能用这段代码一次读取多个在线文件而不会导致段错误? 2) 当文件是不存在的本地文件或不存在的在线文件时,为什么 handle == NULL 条件不成立? (这就是为什么我必须使用 bool 空变量)。
另请注意,我在启动任何线程之前使用了 curl_global_init()。
提前致谢。
编辑:发生段错误时我的 GDB 输出:
Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7ffff2924700 (LWP 3280)]
0x00007ffff7684f3a in ?? () from /usr/lib/x86_64-linux-gnu/libcurl-gnutls.so.4
最佳答案
我终于找到了解决办法。
libCurl 不允许在不同的线程中使用相同的句柄(参见 here ,在关于线程安全的部分),它会导致错误。所以我们不能使用 fopen.c直接读取不同线程中的多个文件。我们必须通过添加 __thread
来修改全局变量 multi_handle
,然后它才能正常工作。
关于c - 在 C 中使用 libcurl 按线程读取一个文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30019587/