2015-02-24 3 views
1

У меня есть вопрос относительно безопасности выполнения параллельных HTTP-запросов с использованием libcurl (C++). При чтении этого вопроса, пожалуйста, имейте в виду, что я имею ограниченное знание об HTTP-запросах в целом.Сделать параллельные запросы на libcurl HTTP

В принципе, допустим, у меня есть две (или более) темы, каждый поток делает HTTP-запрос раз в секунду. (Все запросы сделаны на том же сервере). Как моя программа (или что-то еще?) Отслеживает, какой HTTP-ответ принадлежит протекторам? Я имею в виду, могу ли я быть уверенным, что если запрос A был отправлен из потока 1 и одновременно запросить B из потока 2, и ответы будут возвращены в одно и то же время, правильный ответ (ответ A) будет передаваться в поток 1 и ответ В на поток 2?

Прошу извинить мое невежество в этом вопросе.

Спасибо.

ответ

4

Прежде всего Libcurl является thread safe:

Libcurl разработан и реализован полностью поточно

Как отметил этой официальной документации все что вам нужно сделать, это:

Никогда share libcurl обрабатывает несколько потоков. Вы должны использовать только один дескриптор в одном потоке в любой момент времени.

Кроме того, есть также этот official FAQ entry, что обеспечивает еще несколько уточнений, например, если вы планируете использовать SSL:

Если вы используете Libcurl с OpenSSL питанием в многопоточной среде, вам нужно чтобы обеспечить один или два запорную функцию

Как вы можете видеть, что есть официальный пример, который иллюстрирует многопоточное использование простых ручек на: см multithread.c:

/* This is the callback executed when a new threads starts */ 
static void *pull_one_url(void *url) 
{ 
    CURL *curl; 

    curl = curl_easy_init(); 
    curl_easy_setopt(curl, CURLOPT_URL, url); 
    curl_easy_perform(curl); /* ignores error */ 
    curl_easy_cleanup(curl); 

    return NULL; 
} 

/* ... */ 

/* This is the main loop that creates `NUMT` threads for parallel fetching */ 
for(i=0; i< NUMT; i++) { 
    error = pthread_create(&tid[i], 
          NULL, /* default attributes please */ 
          pull_one_url, 
          (void *)urls[i]); 
    /* ... */ 
} 

Так что не стесняйтесь придать этому примеру пример.

Наконец, помните, что libcurl также предоставляет так называемый multi interface, который предлагает несколько передач с использованием одной нити. Вы можете найти это удобно также в соответствии с вашим вариантом использования.

EDIT

Что касается OpenSSL + мульти-потоков существуют определенные официальные примеры, которые могут помочь:

+0

Очень хороший ответ, спасибо. У меня есть небольшая проблема, понимающая это: http://www.openssl.org/docs/crypto/threads.html#DESCRIPTION У меня нет заголовков openssl.h, я загрузил предварительно скомпилированный двоичный файл, v0. 9.8r для Win64-бит. У вас есть пример этого? Еще раз спасибо. – jensa

+0

Я бы сказал, что это заслуживает (нового) заданного вопроса. – deltheil

+0

См. Мои ответы ниже. – jensa

0

Я попробовал следующее:

static std::mutex* aMutex; 


void locking_function(int mode, int n, const char* file, int line) 
{ 
    if(mode & CRYPTO_LOCK){ 
     std::cout << "Mutex locking\n"; 
     aMutex[n].lock(); 
    } 
    else{ 
     std::cout << "Mutex unlocking\n"; 
     aMutex[n].unlock(); 
    } 
} 

unsigned long id_function() 
{ 
    return (unsigned long)std::hash<std::thread::id>() (std::this_thread::get_id()); 
} 

int thread_setup() 
{ 
    aMutex = new std::mutex[CRYPTO_num_locks()]; 
    if(!aMutex) 
     return 0; 
    else{ 
     CRYPTO_set_id_callback(id_function); 
     CRYPTO_set_locking_callback(locking_function); 
    } 
    return 1; 
} 

int thread_cleanup() 
{ 
    if(!aMutex) 
     return 0; 

    CRYPTO_set_id_callback(NULL); 
    CRYPTO_set_locking_callback(NULL); 
    delete[] aMutex; 
    aMutex = NULL; 
    return 1; 
} 

основан на том, что я нашел здесь: OpenSSL and multi-threads

Когда я создаю завиток рукоятку

curl_ = curl_easy_init(); 

Приговоры «мьютекс замок» и «мьютекс отпирание» распечатана снова и снова очень быстро. Когда я уничтожаю ручку CURL, она останавливается? Это нормально/правильно?

Спасибо.

+1

задавать вопросы о последующих действиях, так как ответы на ваш собственный вопрос просто ошибочны ... –

+0

Извините, я переведу его на новый вопрос. – jensa