gpt4 book ai didi

c++ - curl_easy 和 curl_multi 之间没有区别

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:24:23 24 4
gpt4 key购买 nike

我正在使用 libcurl 执行从我的 C++ 程序到我的 PHP 脚本的 HTTP 请求。
下面的第一个 easy_ 版本运行良好,但速度很慢(在本地主机上每秒 12 个请求)。
没什么奇怪的 - 我使用 ab -n 1000 -c 1 得到了类似的结果。
另一方面,ab -n 1000 -c 100 在每秒 600 个请求时表现得更好。
问题是,使用 libcurl multi 似乎不是并发的。我使用了稍微修改过的示例代码,结果也是大约 12 个请求/秒。

我理解 curl_multi 对吗?我怎样才能达到类似于ab的结果?
附言。我知道这两个代码有点不同,但几乎所有时间都花在了 curl 工作上。

最简单的方法:

CURL *curl;
CURLcode response; // HTTP response

curl = curl_easy_init();

if(curl)
{


curl_easy_setopt(curl, CURLOPT_URL, "http://localhost/process.php");

while(true)
{
if(!requestsQueue.empty())
{
mtx.lock();
string data = requestsQueue.front();
requestsQueue.pop();
mtx.unlock();

const char *post = data.c_str(); //convert string to char used by CURL

curl_easy_setopt(curl, CURLOPT_POSTFIELDS, post);

do
{
response = curl_easy_perform(curl);
} while(response != CURLE_OK);

}
else
{
//there are no request to perform, so wait for them
cout << "Sleeping...\n";
sleep(2);
continue;
}
}

//curl_easy_cleanup(curl);
}
else
{
cout << "CURL init failed!\n";
}

多路:

CURLM *multi_handle;
int still_running; /* keep number of running handles */

/* init a multi stack */
multi_handle = curl_multi_init();

/* add the individual transfers */
for(int i=1;i<=300;i++)
{
CURL *handle;
handle = curl_easy_init();
curl_easy_setopt(handle, CURLOPT_URL, "http://localhost/process.php");
curl_multi_add_handle(multi_handle, handle);
}

/* we start some action by calling perform right away */
curl_multi_perform(multi_handle, &still_running);

do {
struct timeval timeout;
int rc; /* select() return code */

fd_set fdread;
fd_set fdwrite;
fd_set fdexcep;
int maxfd = -1;

long curl_timeo = -1;

FD_ZERO(&fdread);
FD_ZERO(&fdwrite);
FD_ZERO(&fdexcep);

/* set a suitable timeout to play around with */
timeout.tv_sec = 1;
timeout.tv_usec = 0;

curl_multi_timeout(multi_handle, &curl_timeo);
if(curl_timeo >= 0) {
timeout.tv_sec = curl_timeo / 1000;
if(timeout.tv_sec > 1)
timeout.tv_sec = 1;
else
timeout.tv_usec = (curl_timeo % 1000) * 1000;
}

/* get file descriptors from the transfers */
curl_multi_fdset(multi_handle, &fdread, &fdwrite, &fdexcep, &maxfd);

/* In a real-world program you OF COURSE check the return code of the
function calls. On success, the value of maxfd is guaranteed to be
greater or equal than -1. We call select(maxfd + 1, ...), specially in
case of (maxfd == -1), we call select(0, ...), which is basically equal
to sleep. */

rc = select(maxfd+1, &fdread, &fdwrite, &fdexcep, &timeout);

switch(rc) {
case -1:
/* select error */
break;
case 0:
default:
/* timeout or readable/writable sockets */
curl_multi_perform(multi_handle, &still_running);
break;
}
} while(still_running);

curl_multi_cleanup(multi_handle);

curl_easy_cleanup(http_handle);

return 0;

最佳答案

curl_multi 确实可以并行处理任意数量的传输,但它使用同一个线程来完成所有工作。它的副作用是,如果某事在任何地方需要很长时间,该操作会阻止所有其他传输。

如果使用旧的阻塞名称解析器,名称解析器阶段就是这种阻塞操作的一个示例,有时会导致您所描述的情况。其他解释包括应用程序实现的回调由于某种原因需要时间。

您可以构建 libcurl 来代替使用 c-ares 或线程解析器后端,它们都避免了这种阻塞行为,并且更好地允许并发。 线程解析器是 libcurl 中的默认值,多年来(2021 年底)。

关于c++ - curl_easy 和 curl_multi 之间没有区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21514342/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com