当前位置:网站首页>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 .
边栏推荐
猜你喜欢
随机推荐
Es6最新常用知识宝典(能够帮助你解决面试题困惑,编写程序中出现的问题等)
<script>标签内容详解
MySQL optimization
es6新增-运算符的扩展
CityEngine 三维管道建模教程
Applet cloud development form submission and data acquisition in the page
Excel imports long data and changes to 000 at the end
Easypoi excel simple export
Get the multi-functional version of the maximum and minimum values of the internal values of the objects in the array and the full version of the roll call system, and show the effect
微信小程序云开发使用方法-1
Shell script configures root to login to other hosts without secret
Case summary of rotation chart moving speed (constant speed, slow motion)
Beginner's Guide to learning penetration testing
使用js中的(offset,page)实现登录效果
【Es6】forEach,for...in ,for...of专栏,让你通过项目案例快速分辨各种for语句的使用方式及区别(完整版)内部有详细注释
Ucharts chart, pie chart, bar chart and line chart are used in uniapp
redis 源码分析3 间断遍历的实现
路由器loopback口实验
Opendds QoS and custom QoS (timing, timingqospolicy)
STL容器——queue与deque的基本操作








