添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

今天发现如果使用多线程调用curl_easy的接口,并发访问若干https的接口,程序会出现偶尔的崩溃。崩溃位于调用curl_easy_cleanup的时候,最后崩溃的函数位于LIBEAY32.dll中的getrn。google搜索之后发现这是libcurl在使用openssl的时候,根据openssl版本的不同,可能需要设置回调的函数
https://curl.haxx.se/libcurl/c/threadsafe.html

我的libcurl是使用vcpkg安装的,它依赖的openssl版本为1.0.2o,因此需要设置回调函数locking_function和threadid_func。当然,openssl 1.0.2的文档也提到

threadid_func(CRYPTO_THREADID *id) is needed to record the currently-executing thread's identifier into id. The implementation of this callback should not fill in id directly, but should use CRYPTO_THREADID_set_numeric() if thread IDs are numeric, or CRYPTO_THREADID_set_pointer() if they are pointer-based. If the application does not register such a callback using CRYPTO_THREADID_set_callback(), then a default implementation is used - on Windows and BeOS this uses the system's default thread identifying APIs, and on all other platforms it uses the address of errno. The latter is satisfactory for thread-safety if and only if the platform has a thread-local error number facility.

也就是说windows上有获取线程ID的实现,不需要注册threadid的回调

网上的很多例子都是基于官网例子改的,使用了pthread库的相关函数
https://curl.haxx.se/libcurl/c/opensslthreadlock.html

在windows上面使用pthread并不是那么方便。可以参考基于c++11的实现
https://stackoverflow.com/questions/34998440/curl-crashes-in-threaded-calls

基于boost的实现
https://curl.haxx.se/mail/lib-2016-11/0175.html

std::vector<std::mutex> openssl_lock_list(CRYPTO_num_locks());
void openssl_crypto_locking_callback(
    int mode, int type, const char * const, int)
    if (mode & CRYPTO_LOCK) {
        openssl_lock_list[type].lock();
    else {
        openssl_lock_list[type].unlock();
    // 要多线程调用前先设置openssl的lock回调
    CRYPTO_set_locking_callback(openssl_crypto_locking_callback);
原文链接: https://www.jianshu.com/p/18b5ac128bb2 libcurl 一段时间遇到莫名其妙的程序崩溃的情况,开 觉得是 线程 栈溢出 导致 的段错误,专门增加了 线程 栈的大小貌似无效。 线程 也是分离的。用valgrind定位到问题可能出现在 curl 调用 上。 排查的时候也发现了 libcurl 一些额外的坑,现做个总结笔记。 线程 使用 libcurl 访问时,设置了超时时间,而 libcurl 为这个超时信号做任何处理,信号产生而没有信号句柄处理,可能导 注意点1:现象:http短连接超过一定次数后一直返回错误7,即 CURL E_COULDNT_CONNECT 过程有打印:Immediate connect fail for 114.116.228.34: Too many open files 使用netstat查看发现有大量的TCP连接保持在CLOSE_WAIT状态: 原因:也就是说,默认情况下 libcurl 完成一个任务以后,出于重用连接的考虑不 马上关闭 如果没有新的TCP请求来重用这个连接,那么只能等到CLOSE_WAIT cento :http://blog.csdn.net/delphiwcdj/article/details/18284429 1 问题背景 后台系统有一个单 线程 的http接口,为了提高并发处理能力,开启多个 线程 并发在跑,修改后接口的响应确实得到提高,但是server每3分钟出现一次 crash 。原因是系统使用的是 curl -7.21.1(August 11 2010)的 ,此版本并非 线程 安全。遂替换... 后台系统有一个单 线程 的http接口,为了提高并发处理能力,开启多个 线程 并发在跑,修改后接口的响应确实得到提高,但是server每3分钟出现一次 crash 。原因是系统使用的是 curl -7.21.1(August 11 2010)的 ,此版本并非 线程 安全。遂替换了最新的 curl -7.34.0(December 12 2013 使用 curl 访问 http 链接时,用 easy handle,阻塞方式访问时发现 每个访问启动一个 线程 去进行dns 想减少这种消耗,故此采用了 sh = curl _share_init(); curl _share_setopt(sh, CURL SHOPT_SHARE, CURL _LOCK_DATA_DNS);来启用dns cache功能,工作的挺好 后面在多个 线程 里使用同一个 sh