很显然,通过URL传输数据是一个耗费性能的行为。所以,一个非常有必要的策略是通过多线程来加快数据的传输:每个线程分别传输数据的不同部分,理论上就能达到单线程N倍的效率。不过,多线程中使用curl会有一些问题,总结一二,以做参考。
经实际验证,多数崩溃的原因是由于curl对DNS解析的超时机制造成的。经过查询资料得知,这个超时机制是采用alarm+siglongjmp实现的(原理不解),使用到了全局变量,并不是线程安全的,所以需要配置一下DNS解析超时:
curl_easy_setopt(curl, CURLOPT_TIMEOUT, 30L);
curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1L);
官方推荐的初始化实践是:全部初始化函数curl_global_init()
在主线程中调用一次,而每个任务(线程)中调用一次curl_easy_init()
。这是因为curl_global_init()
不是线程安全的,如果curl发现没有全局初始化,会在curl_easy_init()
中调用curl_global_init()
。
有些资料提到,curl在完成一个任务以后,考虑到重连不会马上关闭连接,可能会出现大量的CLOSE_WAIT连接导致性能问题。解决方案是关闭这个重用连接的功能:
curl_easy_setopt(curl, CURLOPT_FORBID_REUSE, 1);