2015-02-24 1 views
1

J'ai une question concernant la sécurité de l'exécution de requêtes HTTP parallèles en utilisant libcurl (C++). En lisant cette question, gardez à l'esprit que j'ai une connaissance limitée des requêtes HTTP en général.Faire des demandes HTTP de libcurl parallèles

Fondamentalement, disons que j'ai deux (ou plus) threads, chaque thread effectue une requête HTTP une fois par seconde. (Toutes les demandes faites sont au même serveur). Comment mon programme (ou autre chose?) Suit-il quelle réponse HTTP appartient à quelle bande de roulement? Je veux dire, je peux être sûr que si la requête A a été envoyée à partir du thread 1, et demander B à partir du thread 2 en même temps, et que les réponses sont renvoyées en même temps, la réponse correcte (réponse A) va au thread 1 réponse B au fil 2?

Veuillez excuser mon ignorance à ce sujet.

Merci.

Répondre

4

tout d'abord libcurl est thread safe:

libcurl est conçu et mis en œuvre entièrement thread-safe

Comme l'a souligné cette documentation officielle tout ce que vous devez faire est:

Jamais Partage libcurl gère entre plusieurs threads. Vous ne devez utiliser qu'une seule poignée dans un seul thread à la fois.

En outre, il y a aussi ce official FAQ entry qui fournit encore plus de précisions, par exemple si vous prévoyez d'utiliser SSL:

Si vous utilisez un libcurl alimenté par OpenSSL dans un environnement multi-thread, vous avez besoin de fournir une ou deux fonctions de verrouillage

Comme vous pouvez le voir, il est un exemple officiel qui illustre une utilisation multi-thread des poignées faciles: voir 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]); 
    /* ... */ 
} 

Alors n'hésitez pas à essayer cet exemple. Enfin, gardez à l'esprit que libcurl fournit également un multi interfacequi offre plusieurs transferts en utilisant un seul thread. Vous pouvez trouver cela pratique en fonction de votre cas d'utilisation.

EDIT

En ce qui concerne OpenSSL + multi-threads il existe des exemples officiels spécifiques qui pourraient aider:

+0

Très bonne réponse, merci. J'ai un peu de mal à comprendre ceci: http://www.openssl.org/docs/crypto/threads.html#DESCRIPTION Je n'ai aucun en-tête openssl.h, j'ai téléchargé un binaire pré-compilé, v0. 9.8r pour Win64 bits. Avez-vous un exemple de cela? Merci encore. – jensa

+0

Je dirais que cela mérite une (nouvelle) question dédiée. – deltheil

+0

S'il vous plaît voir mes réponses ci-dessous. – jensa

0

J'ai essayé les éléments suivants:

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; 
} 

basé sur ce que je trouve ici: OpenSSL and multi-threads

Lorsque je crée une poignée de CURL

curl_ = curl_easy_init(); 

les phrases « verrouillage mutex » et « déverrouillage Mutex » est imprimé sur et plus vraiment rapide. Quand je détruis la poignée CURL, elle s'arrête? Est-ce normal/correct?

Merci.

+1

poser des questions de suivi comme réponses à votre propre question est tout simplement faux ... –

+0

Désolé, je vais passer à une nouvelle question. – jensa