2013-06-26 10 views
5

Mi chiedo cosa succede se due thread chiamano la stessa funzione allo stesso tempo e la funzione è un client UDP che invia un testo al socket.Cosa accade se più di un pthread utilizza una stessa funzione

Considerando il codice seguente, l'ho eseguito ma non ho ancora ricevuto alcun errore. Mi chiedo se dovrebbe essere arrestato in quanto i thread utilizzano la stessa fonte (funzione, variabile, IP, porta) allo stesso tempo e come condividono le fonti? Posso immaginare che il codice seguente sia un uso errato del multi-threading, potresti spiegarmi come dovrebbero essere usati i thread in modo che un thread usi la funzione che nessun altro thread sta usando? In altre parole, come potrebbe essere thread-safe?

come un esempio di codice C su Linux:

void *thread1_fcn(); 
void *thread2_fcn(); 
void msg_send(char *message); 

int main(void){ 
    pthread_t thread1, thread2; 
    pthread_create(&thread1, NULL, thread1_fcn, NULL); 
    pthread_create(&thread2, NULL, thread2_fcn, NULL); 
    while(1){} 
    return 0; 
} 

void *thread1_fcn(){ 
    while(1){ 
     msg_send("hello"); 
     usleep(500); 
    } 
    pthread_exit(NULL); 
} 

void *thread2_fcn(){ 
    while(1){ 
     msg_send("world"); 
     usleep(500); 
    } 
    pthread_exit(NULL); 
} 

void msg_send(char message[]){ 
     struct sockaddr_in si_other; 
     int s=0; 
     char SRV_IP[16] = "192.168.000.002"; 

     s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); 
     memset((char *) &si_other, 0, sizeof(si_other)); 
     si_other.sin_family = AF_INET; 
     si_other.sin_port = htons(12346); 
     si_other.sin_addr.s_addr = htonl(INADDR_ANY); 
     inet_aton(SRV_IP, &si_other.sin_addr); 
     sendto(s, message, 1000, 0, &si_other, sizeof(si_other)); 
     close(s); 
} 
+2

Non c'è alcun problema nel chiamare la stessa funzione (ogni thread ha il proprio contesto di esecuzione indipendente e stack). Ci possono * * * * * * * * * * * * * * * * * * * * * * * * * * * prendere in considerazione l'auto-analisi del codice per vedere quale stato condiviso c'è, se presente, e focalizzare la domanda intorno a questo. – user2246674

+1

La bellezza delle variabili automatiche è che tutto funziona ... automaticamente. –

+1

'thread1_fcn()' e 'thread12_fcn()' dovrebbero ancora essere dichiarati per prendere un argomento 'void *' in modo che corrisponda a ciò che 'pthread_create()' si aspetta. – jxh

risposta

3

Dal momento che si crea e si chiude la presa all'interno msg_send, niente di speciale accadrà. Tutto funzionerà bene.

3

Non ci sono problemi con il tuo codice. Ogni thread, anche se esegue lo stesso codice, ha uno stack separato, quindi un insieme separato di variabili su cui lavora. Nessuna variabile è condivisa.

1

Il codice richiama il comportamento non definito poiché i thread passano letterali stringa piccoli come argomento message, ma la funzione tenta di inviare 1000 byte a partire dall'indirizzo di base message.

Dal sendto è spesso una chiamata diretta al sistema operativo, o si invierà un sacco di immondizia su UDP (o peggio: le informazioni sensibili di sicurezza), o la chiamata di sistema rileverà un fuori di accesso alla memoria limiti e ritorno -1 con errno impostato su qualcosa come EFAULT (probabilmente senza aver inviato alcun dato).

Poiché message è una stringa, è necessario calcolare la sua lunghezza e quindi inviare solo quella quantità (con o senza il terminatore null, che dipende da voi. Il ricevente può ricostruire una stringa terminata null dalla lunghezza del datagramma.)

La funzione non solleva problemi di concorrenza.

La funzione sendto è sicura anche se più thread lo chiamano sullo stesso socket. Se lo si fa su un socket di streaming, tuttavia, è probabile che si verifichino problemi con i dati che vengono interlacciati nel flusso di byte in modi imprevedibili.