当前位置:网站首页>Implementation of synchronization interface of 6 libcurl based on libco
Implementation of synchronization interface of 6 libcurl based on libco
2022-07-19 05:21:00 【HjasnJH】
libcurl:
stay c++ To send http/ https request , I believe many people will use libcurl The library of , The library provides two interfaces
curl_easy_perform Blocking interface
curl_multi_perform Non blocking interface among , Most if it is a client request , It is generally used curl_easy_perform Interface .
By some scenes , such as , There is a service , You need to receive requests from clients , then , Unified by the server like another http The server requests data , Now , The server then uses the blocking interface , It will show that we are stretched .

Our usual practice is to use libcurl Of curl_multi_perform Interface , This interface is implemented by several , Can pass select perhaps poll, But it can't be avoided , In the asynchronous process , We must deal with the mapping of message communication , And maybe your original design , It is the implementation of multithreading through synchronous interface , Now , Whether by a way , Without changing to asynchronous , Without blocking , This requires the use of synergy .
libco Is thread based , therefore , It's best if your system uses other third-party libraries , But you don't want to affect the operation of other third-party libraries , At this time, you need to start the collaboration only in your thread , in other words , Only your thread can take hook system call , such , Other network libraries or third-party libraries of your system IO operation , Will not be affected in any way .

libco You can start in each thread , Now I write a simple test program
int main(int argc, char* argv[])
{
curl_global_init(CURL_GLOBAL_ALL);
ArrayLockFreeQueue<long> vRspList;
ArrayLockFreeQueue<long> vReqList;
std::thread first(TestThread, &vReqList, &vRspList);
int nCnt = 0;
long nReqCount = 0;
while (1)
{
long data;
if (vRspList.try_dequeue(data))
{
printf("GetData from Queue = %d %ld\n", data, GetTickMS());
}
else
{
usleep(1000);
printf("pushData to Queue = %d \n", nReqCount);
vReqList.enqueue(nReqCount++);
}
}
curl_global_cleanup();
return 0;
}among , Two lockless queues are defined , Requests and responses , If you want to see the implementation of lockless queue , In my previous article, I shared the related implementation methods of lockless queue .
Thread started
int EndEventLoop(void* p)
{
return -1;
}
void TestThread(ArrayLockFreeQueue<long>* pReqList, ArrayLockFreeQueue<long>* pRspList)
{
long data = 0;
while (true)
{
if (pReqList->try_dequeue(data))
{
stCoRoutine_t* consumer_routine;
co_create(&consumer_routine, nullptr, Producer, pRspList);
co_resume(consumer_routine);
}
co_eventloop(co_get_epoll_ct(), EndEventLoop, NULL);
}
}Constantly pull data from the queue , I used co_eventloop, But I don't want it to circulate all the time , As a result, I can't get the queue data . So here Tencent libco Provides a return mechanism , I used it
Then there is the realization of producers
void* Producer(void* pArgs)
{
co_enable_hook_sys();
CURL* curl;
CURLcode res;
curl = curl_easy_init();
if (curl) {
//curl_easy_setopt(curl, CURLOPT_URL, "https://example.com/");
// curl_easy_setopt(curl, CURLOPT_URL, "https://www.baidu.com/");
curl_easy_setopt(curl, CURLOPT_URL, "http://192.168.88.130/");
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback);
long nStart = GetTickMS();
// printf("perform begin %ld\n", nStart);
res = curl_easy_perform(curl);
if (res != 0)
{
static int nErrCount = 0;
printf("curl_ret = %d %d\n", res, ++nErrCount);
}
// printf("perform end ret=%d, %ld\n", res, GetTickMS() - nStart);
curl_easy_cleanup(curl);
if (pArgs)
{
ArrayLockFreeQueue<long>* pList = (ArrayLockFreeQueue<long>*)pArgs;
static int nSend = 0;
// printf("push data to queue %ld\n", GetTickMS());
pList->enqueue(nSend++);
}
}
return NULL;
}
Here I simply return a number , When actually applied , We can return a result set pointer , This is very flexible , No restrictions .
This code just shares the general logic implementation . Some modifications can be made and applied to the real environment .
边栏推荐
- 2020-10-22
- Continue from the previous issue: the remaining two methods of the rotation chart
- Cesium 绑定鼠标事件和移除鼠标事件
- Two methods of rotation chart and automatic rotation
- Use (offset, page) in JS to achieve login effect
- Swagger配置与使用
- Excel imports long data and changes to 000 at the end
- MapBox 加载本地离线地形
- 小程序云开发表单提交并在页面中获取数据
- LeetCode53. 最大子数组和
猜你喜欢
随机推荐
How to deal with the mismatch between subtitle files and video files
用户态协议栈-基于netmap的UDP实现
BUUCTF 杂项——二维码
轮播图的两种方法及自动轮播
遍历的方法总结
Internship project 3- change owner
es6新增-数组/对象的解构赋值
LeetCode53. 最大子数组和
Ucharts chart, pie chart, bar chart and line chart are used in uniapp
uniapp 使用uview实现折叠面板
Single arm routing configuration
手把手教你复现Log4j2核弹级漏洞
ArcMap 创建常量栅格并镶嵌至新栅格
B域,M域,O域具体是指什么
云服务器部署WEB项目
Using JS to realize the second level menu of anjuke and the full version (demonstration of precautions and problem points)
SQL injection
循环赛制日程表问题
实习项目1-个性化主页配置
Easypoi之excel模板导出









