libCurl 真的是线程安全的吗?
Is libCurl really thread-safe?
在无法找出 中我的应用程序发生了什么之后,我尝试使用 valgrind 在我的电脑中重现它以查找内存/多线程问题。我在很多地方都看到过这个:
==769== Possible data race during write of size 4 at 0xACD3ADC by thread #13
==769== Locks held: none
==769== at 0x4C36067: memset (in /usr/lib/valgrind/vgpreload_helgrind-amd64-linux.so)
==769== by 0x4E4570D: pthread_create@@GLIBC_2.2.5 (allocatestack.c:249)
==769== by 0x4C30C90: ??? (in /usr/lib/valgrind/vgpreload_helgrind-amd64-linux.so)
==769== by 0x509F957: Curl_thread_create (in /usr/lib/x86_64-linux-gnu/libcurl.so.4.3.0)
==769== by 0x50A261B: Curl_resolver_getaddrinfo (in /usr/lib/x86_64-linux-gnu/libcurl.so.4.3.0)
==769== by 0x5066163: Curl_resolv (in /usr/lib/x86_64-linux-gnu/libcurl.so.4.3.0)
==769== by 0x507D74D: Curl_connect (in /usr/lib/x86_64-linux-gnu/libcurl.so.4.3.0)
==769== by 0x508D62F: multi_runsingle (in /usr/lib/x86_64-linux-gnu/libcurl.so.4.3.0)
==769== by 0x508E180: curl_multi_perform (in /usr/lib/x86_64-linux-gnu/libcurl.so.4.3.0)
==769== by 0x50857B2: curl_easy_perform (in /usr/lib/x86_64-linux-gnu/libcurl.so.4.3.0)
==769== by 0x489D63: ConnectionMgr::checkInternetConnection() (ConnectionMgr.cpp:287)
==769== by 0x490E9E: void std::_Mem_fn<void (ConnectionMgr::*)()>::operator()<, void>(ConnectionMgr*) const (in /home/user/app)
==769==
==769== Address 0xACD3ADC is 44 bytes inside a block of size 304 alloc'd
==769== at 0x4C2DFF0: calloc (in /usr/lib/valgrind/vgpreload_helgrind-amd64-linux.so)
==769== by 0x4012E54: _dl_allocate_tls (dl-tls.c:296)
==769== by 0x4E45DA0: pthread_create@@GLIBC_2.2.5 (allocatestack.c:589)
==769== by 0x4C30C90: ??? (in /usr/lib/valgrind/vgpreload_helgrind-amd64-linux.so)
==769== by 0x509F957: Curl_thread_create (in /usr/lib/x86_64-linux-gnu/libcurl.so.4.3.0)
==769== by 0x50A261B: Curl_resolver_getaddrinfo (in /usr/lib/x86_64-linux-gnu/libcurl.so.4.3.0)
==769== by 0x5066163: Curl_resolv (in /usr/lib/x86_64-linux-gnu/libcurl.so.4.3.0)
==769== by 0x507D74D: Curl_connect (in /usr/lib/x86_64-linux-gnu/libcurl.so.4.3.0)
==769== by 0x508D62F: multi_runsingle (in /usr/lib/x86_64-linux-gnu/libcurl.so.4.3.0)
==769== by 0x508E180: curl_multi_perform (in /usr/lib/x86_64-linux-gnu/libcurl.so.4.3.0)
==769== by 0x50857B2: curl_easy_perform (in /usr/lib/x86_64-linux-gnu/libcurl.so.4.3.0)
==769== by 0x489D63: ConnectionMgr::checkInternetConnection() (ConnectionMgr.cpp:287)
我 运行 在一个单独的线程中的函数就是这个。
void ConnectionMgr::checkInternetConnection()
{
CURL* curl = curl_easy_init();
curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 15);
curl_easy_setopt(curl, CURLOPT_URL,"http://www.google.com");
curl_easy_setopt (curl, CURLOPT_FAILONERROR, 1L);
curl_easy_setopt (curl, CURLOPT_CONNECT_ONLY, 1L);
long responseCode = 404;
curl_easy_perform(curl);
curl_easy_getinfo (curl, CURLINFO_HTTP_CONNECTCODE, &responseCode);
curl_easy_cleanup(curl);
mHasInternet = (responseCode == 200);
}
非常感谢。
是的!
libcurl 在documented restrictions 下是线程安全的。每天都有数百个应用程序以线程方式成功使用它。
有没有错误?当然可以,我们会努力修复所有报告给项目的问题。
也许这个问题有点过时了,但我找到了答案。问题是 Curl 使用信号来通知请求超时,并且似乎无法与 multi-threading 一起正常工作。
为了修复它,我使用了 curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1); 之后它就正常工作了。
在无法找出
==769== Possible data race during write of size 4 at 0xACD3ADC by thread #13
==769== Locks held: none
==769== at 0x4C36067: memset (in /usr/lib/valgrind/vgpreload_helgrind-amd64-linux.so)
==769== by 0x4E4570D: pthread_create@@GLIBC_2.2.5 (allocatestack.c:249)
==769== by 0x4C30C90: ??? (in /usr/lib/valgrind/vgpreload_helgrind-amd64-linux.so)
==769== by 0x509F957: Curl_thread_create (in /usr/lib/x86_64-linux-gnu/libcurl.so.4.3.0)
==769== by 0x50A261B: Curl_resolver_getaddrinfo (in /usr/lib/x86_64-linux-gnu/libcurl.so.4.3.0)
==769== by 0x5066163: Curl_resolv (in /usr/lib/x86_64-linux-gnu/libcurl.so.4.3.0)
==769== by 0x507D74D: Curl_connect (in /usr/lib/x86_64-linux-gnu/libcurl.so.4.3.0)
==769== by 0x508D62F: multi_runsingle (in /usr/lib/x86_64-linux-gnu/libcurl.so.4.3.0)
==769== by 0x508E180: curl_multi_perform (in /usr/lib/x86_64-linux-gnu/libcurl.so.4.3.0)
==769== by 0x50857B2: curl_easy_perform (in /usr/lib/x86_64-linux-gnu/libcurl.so.4.3.0)
==769== by 0x489D63: ConnectionMgr::checkInternetConnection() (ConnectionMgr.cpp:287)
==769== by 0x490E9E: void std::_Mem_fn<void (ConnectionMgr::*)()>::operator()<, void>(ConnectionMgr*) const (in /home/user/app)
==769==
==769== Address 0xACD3ADC is 44 bytes inside a block of size 304 alloc'd
==769== at 0x4C2DFF0: calloc (in /usr/lib/valgrind/vgpreload_helgrind-amd64-linux.so)
==769== by 0x4012E54: _dl_allocate_tls (dl-tls.c:296)
==769== by 0x4E45DA0: pthread_create@@GLIBC_2.2.5 (allocatestack.c:589)
==769== by 0x4C30C90: ??? (in /usr/lib/valgrind/vgpreload_helgrind-amd64-linux.so)
==769== by 0x509F957: Curl_thread_create (in /usr/lib/x86_64-linux-gnu/libcurl.so.4.3.0)
==769== by 0x50A261B: Curl_resolver_getaddrinfo (in /usr/lib/x86_64-linux-gnu/libcurl.so.4.3.0)
==769== by 0x5066163: Curl_resolv (in /usr/lib/x86_64-linux-gnu/libcurl.so.4.3.0)
==769== by 0x507D74D: Curl_connect (in /usr/lib/x86_64-linux-gnu/libcurl.so.4.3.0)
==769== by 0x508D62F: multi_runsingle (in /usr/lib/x86_64-linux-gnu/libcurl.so.4.3.0)
==769== by 0x508E180: curl_multi_perform (in /usr/lib/x86_64-linux-gnu/libcurl.so.4.3.0)
==769== by 0x50857B2: curl_easy_perform (in /usr/lib/x86_64-linux-gnu/libcurl.so.4.3.0)
==769== by 0x489D63: ConnectionMgr::checkInternetConnection() (ConnectionMgr.cpp:287)
我 运行 在一个单独的线程中的函数就是这个。
void ConnectionMgr::checkInternetConnection()
{
CURL* curl = curl_easy_init();
curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 15);
curl_easy_setopt(curl, CURLOPT_URL,"http://www.google.com");
curl_easy_setopt (curl, CURLOPT_FAILONERROR, 1L);
curl_easy_setopt (curl, CURLOPT_CONNECT_ONLY, 1L);
long responseCode = 404;
curl_easy_perform(curl);
curl_easy_getinfo (curl, CURLINFO_HTTP_CONNECTCODE, &responseCode);
curl_easy_cleanup(curl);
mHasInternet = (responseCode == 200);
}
非常感谢。
是的!
libcurl 在documented restrictions 下是线程安全的。每天都有数百个应用程序以线程方式成功使用它。
有没有错误?当然可以,我们会努力修复所有报告给项目的问题。
也许这个问题有点过时了,但我找到了答案。问题是 Curl 使用信号来通知请求超时,并且似乎无法与 multi-threading 一起正常工作。
为了修复它,我使用了 curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1); 之后它就正常工作了。