当前位置:   article > 正文

多线程调用libcurl基于https会导致的crash_libcurl到底有什么毛病 多线程下使用总是崩溃

libcurl到底有什么毛病 多线程下使用总是崩溃

今天发现如果使用多线程调用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

  1. std::vector<std::mutex> openssl_lock_list(CRYPTO_num_locks());
  2. void openssl_crypto_locking_callback(
  3. int mode, int type, const char * const, int)
  4. {
  5. if (mode & CRYPTO_LOCK) {
  6. openssl_lock_list[type].lock();
  7. }
  8. else {
  9. openssl_lock_list[type].unlock();
  10. }
  11. }
  12. // 要多线程调用前先设置openssl的lock回调
  13. CRYPTO_set_locking_callback(openssl_crypto_locking_callback);

 

声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号