1. 概述
很顯然,通過URL傳輸數據是一個耗費性能的行為。所以,一個非常有必要的策略是通過多線程來加快數據的傳輸:每個線程分別傳輸數據的不同部分,理論上就能達到單線程N倍的效率。不過,多線程中使用curl會有一些問題,總結一二,以做參考。
2. 詳論
2.1. 崩潰
經實際驗證,多數崩潰的原因是由於curl對DNS解析的超時機制造成的。經過查詢資料得知,這個超時機制是采用alarm+siglongjmp實現的(原理不解),使用到了全局變量,並不是線程安全的,所以需要配置一下DNS解析超時:
curl_easy_setopt(curl, CURLOPT_TIMEOUT, 30L);
curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1L);
2.2. 初始化
官方推薦的初始化實踐是:全部初始化函數curl_global_init()
在主線程中調用一次,而每個任務(線程)中調用一次curl_easy_init()
。這是因為curl_global_init()
不是線程安全的,如果curl發現沒有全局初始化,會在curl_easy_init()
中調用curl_global_init()
。
2.3. 性能
有些資料提到,curl在完成一個任務以后,考慮到重連不會馬上關閉連接,可能會出現大量的CLOSE_WAIT連接導致性能問題。解決方案是關閉這個重用連接的功能:
curl_easy_setopt(curl, CURLOPT_FORBID_REUSE, 1);