Использование cURL и многопоточности в C ++ - PullRequest
1 голос
/ 26 февраля 2020

У меня есть POST-запрос, который я хочу повторить без какого-либо временного сдвига. Я сделал это с requests в python.

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 кода? Спасибо

1 Ответ

1 голос
/ 26 февраля 2020

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 . Он использует асин * сокеты c вместо потоков.

Вот несколько примеров использования API curl multi: multi-poll. c и 10-at- а-время. c

...