【问题标题】:Using cURL and multi threading in C++在 C++ 中使用 cURL 和多线程
【发布时间】:2020-02-26 15:01:25
【问题描述】:

我有一个 POST 请求,我想在没有任何时间偏移的情况下重复它。我已经在python 中使用requests 完成了它。

import requests
import json

url = 'SOME URL'
headers = {"headers"}
payload ={"some payload here"}
data = json.dumps(payload)
session = requests.Session()

def SendOrder():
    r = session.post(url,data=data,headers=headers)
    print(r.text)

for i in range(2000):
    Thread(target=SendOrder,args=[]).start()

它完美地工作,每个线程在发送帖子请求后自行结束。我在 C++ 中使用 cURL 实现:

int Requst(CURL *curl) {

    curl_easy_perform(curl);
    double tt = 0.000;
    int curlRC = curl_easy_getinfo(curl, CURLINFO_TOTAL_TIME, &tt);
    printf("%.8lf\n", tt);
    return 0;

}
    curl_global_init(CURL_GLOBAL_ALL);
    CURL *curl = curl_easy_init();
        curl_easy_setopt(curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
        curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1);
        curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);
        chunk = curl_slist_append(chunk, "user-agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130 Safari/537.36");
        chunk = curl_slist_append(chunk, "x-requested-with:XMLHttpRequest");
        curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "POST");
        std::string jsonstr = "PAYLOAD";
        curl_easy_setopt(curl, CURLOPT_TCP_KEEPALIVE, 1L);
        curl_easy_setopt(curl, CURLOPT_HTTPHEADER, chunk);
        curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
        curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
        curl_easy_setopt(curl, CURLOPT_VERBOSE, 2L);
        curl_easy_setopt(curl, CURLOPT_POSTFIELDS, jsonstr.c_str());
        curl_easy_setopt(curl, CURLOPT_URL, "url");
        for (int i = 1; i <= 1000; i++) {
            std::thread(Requst, curl);
        }
        curl_easy_cleanup(curl);
        curl_global_cleanup();

我想在调用Request 后自行结束线程。我不太了解 C++。 或者无论如何要制作类似python代码的东西? 谢谢

【问题讨论】:

    标签: c++ python-3.x curl python-requests httprequest


    【解决方案1】:

    std::thread 只是原生(实际)线程的包装类。在 std::thread 实例被销毁之前,您应该保留它并保留 join(),否则 std::thread 的析构函数将中止程序。

    您还应该在线程内调用curl_easy_*

    类似的东西

    std::vector<std::thread> threads;
    for (int i = 1; i <= 1000; i++) {
       threads.emplace_back([&]{ // creates and starts a thread
           CURL *curl = curl_easy_init();
           curl_easy_setopt(...
           . . .
           curl_easy_perform();
           curl_easy_cleanup(curl);
       });
    }
    for (auto& t : threads) { // wait for all threads to finish
        t.join();
    }
    

    话虽如此,为了获得良好的性能,最好使用curl multi API。它使用异步套接字而不是线程。

    以下是一些如何使用 curl 多 API 的示例:multi-poll.c10-at-a-time.c

    【讨论】:

    • 非常感谢。 Curl Multi API 同时发送请求。但我想在没有任何时间转移的情况下一个接一个地发送它们。您的代码完美地完成了它。是否可以只定义一个curl 处理程序实例并使用它来发送请求?我的意思是,CURL *curl = curl_easy_init(); 只定义了一次并使用curl_easy_perform(); 来创建线程?
    • 使用线程,请求也将同时发送。要一个接一个地发送和接收请求,您只需要一个for-loop。单个CURL*是一个请求,不能多次执行。
    • 如何在不等待响应的情况下一个接一个地发送请求?每个请求需要 30 毫秒,我只想在没有 30 毫秒延迟的情况下发送它们。
    • @rustyx 您的代码缺少 curl_global_init();功能
    • 另外,这可能是使用多 API 使用线程的更好示例:curl.se/libcurl/c/multithread.html
    猜你喜欢
    • 2012-09-05
    • 1970-01-01
    • 1970-01-01
    • 2020-08-11
    • 1970-01-01
    • 2020-12-02
    • 1970-01-01
    • 1970-01-01
    • 2016-12-19
    相关资源
    最近更新 更多