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

Nho*_*yen 10 c++ curl asynchronous libcurl

我来curl同步使用http请求.我的问题是如何异步进行?

我做了一些搜索,引导我curl_multi_*从这个问题和这个例子的界面文档,但它根本没有解决任何问题.

我的简化代码:

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();
Run Code Online (Sandbox Code Playgroud)

回调方法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;
}
Run Code Online (Sandbox Code Playgroud)

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

Rem*_*eau 8

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

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

当您想要调用传输数据时,您的应用程序可以从libcurl获取知识,这样您就不必像繁忙一样忙于循环并调用curl_multi_perform(3).curl_multi_fdset(3)提供了一个接口,您可以使用该接口从libcurl中提取fd_sets以在select()或poll()调用中使用,以便了解何时多堆栈中的传输可能需要引起注意.这也使您的程序可以很容易地同时等待您自己的私有文件描述符上的输入,或者如果您需要,可能偶尔会超时.

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

当应用程序发现multi_handle的数据可用或超时已过时,应用程序应该调用此函数来读取/写入当前正在读取或写入的内容等.一旦读取/写入,curl_multi_perform()就会返回完成.此功能不要求实际上有任何可用于读取的数据或可以写入数据,可以调用它以防万一.它将写入仍在第二个参数的整数指针中传输数据的句柄数.

如果running_handles的数量从上一次调用更改(或者小于您添加到多句柄的简易句柄的数量),则表示有一个或多个传输较少"正在运行".然后,您可以调用curl_multi_info_read(3)来获取有关每个已完成传输的信息,并且返回的信息包括CURLcode等.如果添加的句柄很快失败,则可能永远不会将其视为running_handle.

return_handles在返回此函数时设置为零(0)时,不再进行任何传输.

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

您链接的博客文章提到了这种循环:

代码可以像

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

//在一些调用每个帧的更新循环中
http:Update();

您没有在代码中进行任何循环,这就是您的回调未被调用的原因.当您拨打curl_multi_perform()一次电话时,尚未收到新数据.

  • `curl_multi_perform()`的目的是让你在curl繁忙时做其他事情,而不必使用线程.如果你使用一个线程,你也可以使用`curl_easy_perform()`.使用`curl_multi_perform()`,你可以做一些其他工作,然后轮询curl的状态并调用`curl_multi_perform()`如果准备就绪,然后做一些其他工作,然后轮询curl的状态,依此类推.在你的例子中,你还没有在循环中做其他工作,这就是为什么你会感到困惑. (2认同)