多线程的libcurl的使用
摘要: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的使用的更多相关文章
- 多线程使用libcurl
curl默认情况下有两个地方是线程不安全的, 需要特殊处理, 1是curl_global_init 这个函数必须单线程调用, 2是默认多线程调用https会莫名其妙的挂掉, 以下是网上的解决方案 ht ...
- VC使用libcurl模拟登录CSDN并自动评论资源以获取积分
环境:Win7 64位+VC2008 软件及源码下载:(http://pan.baidu.com/s/1jGE52pK) 涉及到的知识点: C++多线程编程 libcurl的使用(包括发送http请求 ...
- libcurl模拟登录CSDN并自动评论资源以获取积分
软件及源码下载:(http://pan.baidu.com/s/1jGE52pK) 涉及到的知识点: C++多线程编程 libcurl的使用(包括发送http请求.发送cookie给服务器.保存coo ...
- curl raise 信号出core
在使用c++多线程使用libcurl抓取网页时,遇到程序随机core掉的情况,gdb 一下出错信息有这么一条:longjmp causes uninitialized stack frame. 在网上 ...
- Libcurl多线程crash问题(cento)
cento :http://blog.csdn.net/delphiwcdj/article/details/18284429 1 问题背景 后台系统有一个单线程的http接口,为了提高并发处理能力, ...
- libcurl多线程超时设置不安全(转)
from http://www.cnblogs.com/kex1n/p/4135263.html (1), 超时(timeout) libcurl 是 一个很不错的库,支持http,ftp等很多的协议 ...
- libcurl的封装,支持同步异步请求,支持多线程下载,支持https
最近在做一个项目,需要用到http get post等 需求分析需要做到同步和异步,异步请求的返回以可选的回调通知的方式进行. 本人以Linux为例,一步一步的来实现. 配置并且编译libcurl我以 ...
- libcurl 多线程使用注意事项 - Balder~专栏 - 博客频道 - CSDN.NET
libcurl 多线程使用注意事项 - Balder~专栏 - 博客频道 - CSDN.NET libcurl 多线程使用注意事项 分类: C/C++学习 2012-05-24 18:48 2843人 ...
- HTTP多线程下载+断点续传(libcurl库)
目录索引: 一.LibCurl基本编程框架 二.一些基本的函数 三.curl_easy_setopt函数部分选项介绍 四.curl_easy_perform 函数说明(error 状态码) 五.lib ...
随机推荐
- 解决Tensorflow ValueError: Failed to convert a NumPy array to a Tensor (Unsupported object type numpy.ndarray)
问题描述 在将一个数组送入tensorflow训练时,报错如下: ValueError: Failed to convert a NumPy array to a Tensor (Unsupporte ...
- Spring Boot发布2.6.2、2.5.8:升级log4j2到2.17.0
12月22日,Spring官方发布了Spring Boot 2.5.8(包括46个错误修复.文档改进和依赖项升级)和2.6.2(包括55个错误修复.文档改进和依赖项升级). 这两个版本均为缺陷修复版本 ...
- LuoguP1785 漂亮的绝杀 题解
Content 因太占排版,请自己去题面查看. Solution 声明:以下和题面相同的变量的意义均和题面相同. 这个题目 \(\texttt{if}\) 操作很多,其他的就是纯模拟. 首先,我们先判 ...
- CF1108A Two distinct points 题解
Content 有 \(q\) 次询问,每次询问给定四个数 \(l_1,r_1,l_2,r_2\).对于每次询问,找到两个数 \(a,b\),使得 \(l_1\leqslant a\leqslant ...
- tomcat下部署两个工程时,只有一个可以访问,另一个出现404错误,该如何解决
tomcat下部署两个工程时,只有一个可以访问,另一个出现404错误,该如何解决 在开发新项目的时候,有时候为了省时,直接把曾经做过的项目工程A拷贝成改名为B工程,然后再在B工程上进行功能的开发, 此 ...
- navicat模型分享方法
一. 查看模型保存路径选中模型如:<app-订单模型>,点击右键,对象信息,可以看到文件位置:C:\Users\Administrator\Documents\Navicat\Premiu ...
- 【进阶】uniapp复现微信相册功能之【图视频编辑 + 压缩】
基于uniapp + vue实现微信相册,在实现了微信相册的基础上增加以下功能 1: 图片编辑 2: 视频编辑 3: 文件压缩 技术实现 开发环境:HbuilderX + nodejs 技术框架:un ...
- 【LeetCode】136. Single Number 解题报告(Java & Python)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 异或 字典 日期 [LeetCode] 题目地址:h ...
- 【LeetCode】985. Sum of Even Numbers After Queries 解题报告(C++)
作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 暴力 找规律 日期 题目地址:https://lee ...
- 【LeetCode】813. Largest Sum of Averages 解题报告(Python)
[LeetCode]813. Largest Sum of Averages 解题报告(Python) 标签(空格分隔): LeetCode 作者: 负雪明烛 id: fuxuemingzhu 个人博 ...