libcurl多线程超时设置不安全(转)
from http://www.cnblogs.com/kex1n/p/4135263.html
(1), 超时(timeout)
libcurl 是 一个很不错的库,支持http,ftp等很多的协议。使用库最大的心得就是,不仔细看文档,仅仅看着例子就写程序,是一件危险的事情。我的程序崩溃了,我 怀疑是自己代码写的问题,后来发现是库没用对。不仔细看文档(有时候文档本身也比较差劲,这时除了看仔细外,还要多动脑子,考虑它是怎么实现的),后果很 严重。不加思索的使用别人的库或者代码,有时候很惬意,但是出问题时,却是寝食难安的。
1. CURLcode curl_global_init(long flags); 在多线程应用中,需要在主线程中调用这个函数。这个函数设置libcurl所需的环境。通常情况,如果不显式的调用它,第一次调用 curl_easy_init()时,curl_easy_init 会调用 curl_global_init,在单线程环境下,这不是问题。但是多线程下就不行了,因为curl_global_init不是线程安全的。在多个线 程中调用curl_easy_int,然后如果两个线程同时发现curl_global_init还没有被调用,同时调用 curl_global_init,悲剧就发生了。这种情况发生的概率很小,但可能性是存在的。
2. libcurl 有个很好的特性,它甚至可以控制域名解析的超时。但是在默认情况下,它是使用alarm + siglongjmp 实现的。用alarm在多线程下做超时,本身就几乎不可能。如果只是使用alarm,并不会导致程序崩溃,但是,再加上siglongjmp,就要命了 (程序崩溃的很可怕,core中几乎看不出有用信息),因为其需要一个sigjmp_buf型的全局变量,多线程修改它。(通常情况下,可以每个线程一个 sigjmp_buf 型的变量,这种情况下,多线程中使用 siglongjmp 是没有问题的,但是libcurl只有一个全局变量,所有的线程都会用)。
具体是类似 curl_easy_setopt(curl, CURLOPT_TIMEOUT, 30L) 的超时设置,导致alarm的使用(估计发生在域名解析阶段),如前所述,这在多线程中是不行的。解决方式是禁用掉alarm这种超时, curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1L)。
这样,多线程中使用超时就安全了。但是域名解析就没了超时机制,碰到很慢的域名解析,也很麻烦。文档的建议是 Consider building libcurl with c-ares support to enable asynchronous DNS lookups, which enables nice timeouts for name resolves without signals. c-ares 是异步的 DNS 解决方案。
引自:http://gcoder.blogbus.com/logs/54871550.html
调用libcurl下载,然后使用netstat查看发现有大量的TCP连接保持在CLOSE_WAIT状态
查看libcurl的文档说明,有这样一个选项:
CURLOPT_FORBID_REUSE
Pass a long. Set to 1 to make the next transfer explicitly close the connection when done. Normally, libcurl keeps all connections alive when done with one transfer in case a succeeding one follows that can re-use them. This option should be used with caution and only if you understand what it does. Set to 0 to have libcurl keep the connection open for possible later re-use (default behavior).
也就是说,默认情况下libcurl完成一个任务以后,出于重用连接的考虑不会马上关闭
如果没有新的TCP请求来重用这个连接,那么只能等到CLOSE_WAIT超时,这个时间默认在7200秒甚至更高,太多的CLOSE_WAIT连接会导致性能问题
解决方法:
curl_easy_setopt(curl, CURLOPT_FORBID_REUSE, 1);
最好再修改一下TCP参数调低CLOSE_WAIT和TIME_WAIT的超时时间
libcurl多线程超时设置不安全(转)的更多相关文章
- libcurl多线程超时设置不安全
from http://blog.csdn.net/sctq8888/article/details/10031219 (1), 超时(timeout) libcurl 是 一个很不错的库,支持htt ...
- libcurl使用easy模式阻塞卡死等问题的完美解决---超时设置
libcurl使用时疑难问题: 在使用libcurl时, jwisp发现, curl_easy_perform是阻塞的方式进行下载的, curl_easy_perform执行后,程序会在这里阻塞等待下 ...
- libcurl 多线程使用注意事项 - Balder~专栏 - 博客频道 - CSDN.NET
libcurl 多线程使用注意事项 - Balder~专栏 - 博客频道 - CSDN.NET libcurl 多线程使用注意事项 分类: C/C++学习 2012-05-24 18:48 2843人 ...
- c++比例-libcurl多线程并发时的core【转载】
转自: https://www.cnblogs.com/edgeyang/articles/3722035.html 浅析libcurl多线程安全问题 背景:使用多线程libcurl发送请求,在未设置 ...
- 进程线程协程补充、docker-compose一键部署项目、搭建代理池、requests超时设置、认证设置、异常处理、上传文件
今日内容概要 补充:进程,线程,协程 docker-compose一键部署演示 搭建代理池 requests超时设置 requests认证设置 requests异常处理 requests上传文件 内容 ...
- delphi tidhttp 超时设置无效的解决方法
现在delphi都发布到xe8了,tidhttp还有缺陷,那就是超时设置在没有网络或者连不上服务器的时候是无效的,不管你设置为多少都要10-20秒.connectTimeout和readTimeout ...
- Linux串口中的超时设置
在Linux下使用串口通信时,默认的阻塞模式是不实用的.而采用select或epoll机制的非阻塞模式,写代码有比较麻烦.幸好Linux的串口自己就带有超时机制. Linux下使用termios.h中 ...
- JAVA多线程超时加载当网页图片
先上图: 这一次没有采取正则匹配,而采取了最简单的java分割和替代方法进行筛选图片 它能够筛选如下的图片并保存到指定的文件夹 如: “http://xxxx/xxxx/xxx.jpg” 'http: ...
- org.apache.http.client.HttpClient; HttpClient 4.3超时设置
可用的code import org.apache.commons.lang.StringUtils;import org.apache.http.HttpEntity;import org.apac ...
随机推荐
- JSBinding+SharpKit / 更新的原理
首先,其实不是热更新,而是更新. 热更新意思是不重启游戏,但只要你脚本里有存储数据,就不可能.所以只能叫更新. 但大家都这么说,所以... 先举个具体的例子: 如果是C#:在 Prefab 的 Gam ...
- 极值问题(acms)
[问题描述] 已知m.n为整数,且满足下列两个条件: ① m.n∈{1,2,…,k},即1≤m,n≤k,(1≤k≤109). ②(n2-m*n-m2)2=1 你的任务是:编程输入正整数k,求一组满足上 ...
- 转:RabbitMQ基础知识
RabbitMQ基础知识 一.背景 RabbitMQ是一个由erlang开发的AMQP(Advanced Message Queue )的开源实现.AMQP 的出现其实也是应了广大人民群众的需求,虽然 ...
- python之文件操作
python文件操作 举例:将一个文本文件转成十六进制形式后,保存到另一个文件中. f = open('mycert.cr', 'r') str = f.read() list = [] for ch ...
- [翻译] WCF运行时架构
原文地址 http://www.cnblogs.com/idior/articles/971252.html 介绍 WCF具有非常易用的编程模型,服务开发者在掌握ABC的概念后可以很容易的使用WCF去 ...
- Oracle11g的delayed failed logins特性引起的性能问题
用户反映修改密码后程序明显变慢,查看AWR发现: ASH信息如下: 进一步验证: SQL>select event,p1 from v$session t where t.username is ...
- NodeJs http.get 方法请求时间过长问题处理!
NodeJs 获取网页内容 http.get 默认请求超时过长了,程序要卡死好一会. 根据网上资料现改造了一个带超时设置的获取网页内容方法. 主要方法使用 setTimeout 来超时, 代码如下: ...
- spring + spring mvc可能会遇到的问题
Spring容器优先加载由ServletContextListener(对应applicationContext.xml)产生的父容器,而SpringMVC(对应mvc_dispatcher_serv ...
- 使用springMVC实现文件上传和下载之环境配置与上传
最近的项目中用到了文件的上传和下载功能,任务分配给了其他的同时完成.如今项目结束告一段落,我觉着这个功能比较重要,因此特意把它提取出来自己进行了尝试. 一. 基础配置: maven导包及配置pom.x ...
- decimal,float和double的区别
http://www.cnblogs.com/yellowapplemylove/archive/2011/08/23/2150316.html 一直很奇怪C#的预定义数据类型中为什么加了一个deci ...