c++ - 如何在 C++ 中异步执行 curl_multi_perform()?

标签 c++ curl asynchronous libcurl

我开始使用 curl 同步执行 http 请求。我的问题是如何异步执行此操作?

我做了一些搜索,从这个 question 找到了 curl_multi_* 接口(interface)的文档。还有这个example但它根本没有解决任何问题。

我的简化代码:

CURLM *curlm;
int handle_count = 0;
curlm = curl_multi_init();

CURL *curl = NULL;
curl = curl_easy_init();

if(curl)
{
    curl_easy_setopt(curl, CURLOPT_URL, "https://stackoverflow.com/");
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writeCallback);
    curl_multi_add_handle(curlm, curl);
    curl_multi_perform(curlm, &handle_count);
}

curl_global_cleanup();

回调方法 writeCallback 没有被调用,也没有任何反应。

请多多指教。

编辑:

根据@Remy 的以下回答,我得到了这个,但似乎并不是我真正需要的。因为使用循环仍然是一个阻塞。如果我做错了或误解了什么,请告诉我。我实际上是 C++ 的新手。

这里又是我的代码:

int main(int argc, const char * argv[])
{
    using namespace std;
    CURLM *curlm;
    int handle_count;
    curlm = curl_multi_init();

    CURL *curl1 = NULL;
    curl1 = curl_easy_init();

    CURL *curl2 = NULL;
    curl2 = curl_easy_init();

    if(curl1 && curl2)
    {
        curl_easy_setopt(curl1, CURLOPT_URL, "https://stackoverflow.com/");
        curl_easy_setopt(curl1, CURLOPT_WRITEFUNCTION, writeCallback);
        curl_multi_add_handle(curlm, curl1);

        curl_easy_setopt(curl2, CURLOPT_URL, "http://google.com/");
        curl_easy_setopt(curl2, CURLOPT_WRITEFUNCTION, writeCallback);
        curl_multi_add_handle(curlm, curl2);

        CURLMcode code;
        while(1)
        {
            code = curl_multi_perform(curlm, &handle_count);

            if(handle_count == 0)
            {
                break;
            }
        }
    }

    curl_global_cleanup();

    cout << "Hello, World!\n";
    return 0;
}

我现在可以同时执行 2 个 http 请求。回调被调用但仍然需要在执行以下行之前完成。我必须考虑线程吗?

最佳答案

再次仔细阅读文档,尤其是以下部分:

http://curl.haxx.se/libcurl/c/libcurl-multi.html

Your application can acquire knowledge from libcurl when it would like to get invoked to transfer data, so that you don't have to busy-loop and call that curl_multi_perform(3) like crazy. curl_multi_fdset(3) offers an interface using which you can extract fd_sets from libcurl to use in select() or poll() calls in order to get to know when the transfers in the multi stack might need attention. This also makes it very easy for your program to wait for input on your own private file descriptors at the same time or perhaps timeout every now and then, should you want that.

http://curl.haxx.se/libcurl/c/curl_multi_perform.html

When an application has found out there's data available for the multi_handle or a timeout has elapsed, the application should call this function to read/write whatever there is to read or write right now etc. curl_multi_perform() returns as soon as the reads/writes are done. This function does not require that there actually is any data available for reading or that data can be written, it can be called just in case. It will write the number of handles that still transfer data in the second argument's integer-pointer.

If the amount of running_handles is changed from the previous call (or is less than the amount of easy handles you've added to the multi handle), you know that there is one or more transfers less "running". You can then call curl_multi_info_read(3) to get information about each individual completed transfer, and that returned info includes CURLcode and more. If an added handle fails very quickly, it may never be counted as a running_handle.

When running_handles is set to zero (0) on the return of this function, there is no longer any transfers in progress.

换句话说,您需要运行一个循环来轮询 libcurl 的状态,每当有数据等待传输时调用 curl_multi_perform(),根据需要重复直到没有任何数据要传输.

blog article你链接到提到这个循环:

The code can be used like

Http http;
http:AddRequest("http://www.google.com");

// In some update loop called each frame
http:Update();

你没有在你的代码中做任何循环,这就是你的回调没有被调用的原因。当您调用一次 curl_multi_perform() 时,尚未收到新数据。

关于c++ - 如何在 C++ 中异步执行 curl_multi_perform()?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24288513/

相关文章:

c++ - gluPerspective 和 glOrtho 都没有任何效果

c++ - ZeroMQ 在多线程应用程序中处理中断

c++ - Clang - 检测头文件何时完成

php - 使用 Kohana Request 时如何设置 CURL 选项

node.js async.js nextTick vs setImmediate

c# - Async 和 Await 命令编译没有错误,但不会让我的 Windows 窗体响应

c++ - Libpqxx 连接池

java - 所需的字符串参数 'surname' 不存在

PHP SSL3_GET_SERVER_CERTIFICATE :certificate verify failed

memory - 为什么将 OpenCL 内核排队执行会导致程序的内存使用增加?