摘要:libcurl在多线程中,采用https访问,经常运行一段时间,会出现crash。

libcurl的在多线程中的使用特别注意的有两点:

1. curl的句柄不能多线程共享。

2. ssl访问时, openssl是线程不安全的。

知道了这两点,就能解决libcurl无故crash的问题了。

第一点:每个线程初始化一个句柄,供这个线程使用。

第二点:需要添加回调函数,进行线程锁。

参考代码如下:

#include <stdio.h>
#include <pthread.h>
#include <curl/curl.h> #define NUMT 4 /* we have this global to let the callback get easy access to it */
static pthread_mutex_t *lockarray; #ifdef USE_OPENSSL
#include <openssl/crypto.h>
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;
printf("crypto num is %d\r\n", CRYPTO_num_locks());
lockarray = (pthread_mutex_t *)OPENSSL_malloc(CRYPTO_num_locks() *
sizeof(pthread_mutex_t));
for(i = 0; i<CRYPTO_num_locks(); i++) {
pthread_mutex_init(&(lockarray[i]), NULL);
} CRYPTO_set_id_callback((unsigned long (*)())thread_id);
CRYPTO_set_locking_callback((void (*)())lock_callback);
} static void kill_locks(void)
{
int i; CRYPTO_set_locking_callback(NULL);
for(i = 0; i<CRYPTO_num_locks(); i++)
pthread_mutex_destroy(&(lockarray[i])); OPENSSL_free(lockarray);
} /* List of URLs to fetch.*/
const char * const urls[]= {
"https://www.example.com/",
"https://www2.example.com/",
"https://www3.example.com/",
"https://www4.example.com/",
}; static void *pull_one_url(void *url)
{
CURL *curl; curl = curl_easy_init();//每个线程初始化一个句柄,绝对不能混用。
curl_easy_setopt(curl, CURLOPT_URL, url);
/* this example doesn't verify the server's certificate, which means we
might be downloading stuff from an impostor */
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
curl_easy_perform(curl); /* ignores error */
curl_easy_cleanup(curl); return NULL;
} int main(int argc, char **argv)
{
pthread_t tid[NUMT];
int i;
(void)argc; /* we don't use any arguments in this example */
(void)argv; /* Must initialize libcurl before any threads are started */
curl_global_init(CURL_GLOBAL_ALL); init_locks();//初始化openssl的回调函数,加载线程锁 for(i = 0; i< NUMT; i++) {
int error = pthread_create(&tid[i],
NULL, /* default attributes please */
pull_one_url,
(void *)urls[i]);
if(0 != error)
fprintf(stderr, "Couldn't run thread number %d, errno %d\n", i, error);
else
fprintf(stderr, "Thread %d, gets %s\n", i, urls[i]);
} /* now wait for all threads to terminate */ for(i = 0; i< NUMT; i++) {
pthread_join(tid[i], NULL);
fprintf(stderr, "Thread %d terminated\n", i);
} kill_locks();//销毁openssl线程锁 return 0;
}

多线程的libcurl的使用的更多相关文章

  1. 多线程使用libcurl

    curl默认情况下有两个地方是线程不安全的, 需要特殊处理, 1是curl_global_init 这个函数必须单线程调用, 2是默认多线程调用https会莫名其妙的挂掉, 以下是网上的解决方案 ht ...

  2. VC使用libcurl模拟登录CSDN并自动评论资源以获取积分

    环境:Win7 64位+VC2008 软件及源码下载:(http://pan.baidu.com/s/1jGE52pK) 涉及到的知识点: C++多线程编程 libcurl的使用(包括发送http请求 ...

  3. libcurl模拟登录CSDN并自动评论资源以获取积分

    软件及源码下载:(http://pan.baidu.com/s/1jGE52pK) 涉及到的知识点: C++多线程编程 libcurl的使用(包括发送http请求.发送cookie给服务器.保存coo ...

  4. curl raise 信号出core

    在使用c++多线程使用libcurl抓取网页时,遇到程序随机core掉的情况,gdb 一下出错信息有这么一条:longjmp causes uninitialized stack frame. 在网上 ...

  5. Libcurl多线程crash问题(cento)

    cento :http://blog.csdn.net/delphiwcdj/article/details/18284429 1 问题背景 后台系统有一个单线程的http接口,为了提高并发处理能力, ...

  6. libcurl多线程超时设置不安全(转)

    from http://www.cnblogs.com/kex1n/p/4135263.html (1), 超时(timeout) libcurl 是 一个很不错的库,支持http,ftp等很多的协议 ...

  7. libcurl的封装,支持同步异步请求,支持多线程下载,支持https

    最近在做一个项目,需要用到http get post等 需求分析需要做到同步和异步,异步请求的返回以可选的回调通知的方式进行. 本人以Linux为例,一步一步的来实现. 配置并且编译libcurl我以 ...

  8. libcurl 多线程使用注意事项 - Balder~专栏 - 博客频道 - CSDN.NET

    libcurl 多线程使用注意事项 - Balder~专栏 - 博客频道 - CSDN.NET libcurl 多线程使用注意事项 分类: C/C++学习 2012-05-24 18:48 2843人 ...

  9. HTTP多线程下载+断点续传(libcurl库)

    目录索引: 一.LibCurl基本编程框架 二.一些基本的函数 三.curl_easy_setopt函数部分选项介绍 四.curl_easy_perform 函数说明(error 状态码) 五.lib ...

随机推荐

  1. 任务信息的高级选项(Project)

    <Project2016 企业项目管理实践>张会斌 董方好 编著 张同学说,[高级]选项卡很重要,嗯,本妖深以为然! 这里的[高级]选项卡,是指[任务信息]里的,在默认视图下,只要双击某任 ...

  2. CF116B Little Pigs and Wolves 题解

    Content 有一张 \(n\times m\) 的地图,其中,\(\texttt{P}\) 代表小猪,\(\texttt{W}\) 代表狼.如果狼的上下左右有一头以上的小猪,那么它会吃掉其中相邻的 ...

  3. C++ 11 新特性:函数声明auto

    1.概览 1.1 函数名中的箭头,用来表明函数的return type,其使用在函数的返回类型需要通过模板参数进行推导,使用在decltype()和declval()不方便的场景 2.正文 c++ 中 ...

  4. 【LeetCode】170. Two Sum III - Data structure design 解题报告(C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客:http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 数组+字典 平衡查找树+双指针 日期 题目地址:htt ...

  5. 【LeetCode】1023. Binary String With Substrings Representing 1 To N 解题报告(Python)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 日期 题目地址:https://leetcode.c ...

  6. 【LeetCode】622. Design Circular Queue 解题报告(Python & C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 用直的代替弯的 数组循环利用 日期 题目地址:htt ...

  7. 1306 - Solutions to an Equation

    1306 - Solutions to an Equation    PDF (English) Statistics Forum Time Limit: 2 second(s) Memory Lim ...

  8. [转]opencv2早期调用函数

    1.cvLoadImage:将图像文件加载至内存: 2.cvNamedWindow:在屏幕上创建一个窗口: 3.cvShowImage:在一个已创建好的窗口中显示图像: 4.cvWaitKey:使程序 ...

  9. Spring企业级程序设计 • 【第3章 面向切面编程】

    全部章节   >>>> 本章目录 3.1 AOP基本概念和术语 3.1.1 AOP概念 3.1.2 AOP的术语解释 3.1.3 通知类型介绍 3.1.4 通过AOP模拟事务操 ...

  10. Android物联网应用程序开发(智慧园区)—— 园区监控系统界面

    效果图: 布局代码: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:a ...