最近使用libcurl做https请求,发现多线程下,并发压力下很容易崩溃,查了下api文档,原来libcurl需要第三方库支持ssl,而我这边涌的是openssl,openssl不是线程安全的,需要实现相关的锁设置才支持,具体如下
Multi-threading Issues
The first basic rule is that you must never simultaneously
share a libcurl handle (be it easy or multi or whatever) between
multiple threads. Only use one handle in one thread at any time.
You can pass the handles around among threads, but you must never
use a single handle from more than one thread at any given
time.
libcurl is completely thread safe, except for two issues:
signals and SSL/TLS handlers. Signals are used for timing out name
resolves (during DNS lookup) - when built without c-ares support
and not on Windows.
If you are accessing HTTPS or FTPS URLs in a multi-threaded
manner, you are then of course using the underlying SSL library
multi-threaded and those libs might have their own requirements on
this issue. Basically, you need to provide one or two functions to
allow it to function properly. For all details, see this:
OpenSSL
http://www.openssl.org/docs/crypto/threads.html#DESCRIPTION
GnuTLS
http://www.gnu.org/software/gnutls/manual/html_node/Multi_002dthreaded-applications.html
is claimed to be thread-safe already without
anything required.
PolarSSL
Required actions unknown.
yassl
Required actions unknown.
axTLS
Required actions unknown.
Secure Transport
The engine is fully thread-safe, and no
additional steps are required.
When using multiple threads you should set the
CURLOPT_NOSIGNAL option to 1 for all handles. Everything will or
might work fine except that timeouts are not honored during the DNS
lookup - which you can work around by building libcurl with c-ares
support. c-ares is a library that provides asynchronous name
resolves. On some platforms, libcurl simply will not function
properly multi-threaded unless this option is set.
Also, note that CURLOPT_DNS_USE_GLOBAL_CACHE is not
thread-safe.
注意可以参考demo(threaded-ssl.c)
#define USE_OPENSSL
#include
#include
#include
#define NUMT 4
static pthread_mutex_t *lockarray;
#ifdef USE_OPENSSL
#include
static void lock_callback(int mode, int type, char *file, int
line)
(void)file;
(void)line;
if (mode & CRYPTO_LOCK)
pthread_mutex_lock(&(lockarray[type]));
else {
pthread_mutex_unlock(&(lockarray[type]));
static unsigned long thread_id(void)
unsigned long ret;
ret=(unsigned long)pthread_self();
return(ret);
static void init_locks(void)
int i;
lockarray=(pthread_mutex_t
*)OPENSSL_malloc(CRYPTO_num_locks() *
新浪简介
|
About Sina
|
广告服务
|
联系我们
|
招聘信息
|
网站律师
|
SINA English
|
产品答疑