Sto scrivendo un server TCP simultanee che deve gestire più connessioni con il 'thread per ogni connessione' approccio (usando un pool di filo). Il mio dubbio è su quale sia il modo più ottimale per ogni thread per ottenere un descrittore di file diverso.Calling accetta() da più thread
Ho trovato che i prossimi due metodi sono i più consigliati:
- Un filo conduttore che
accepts()
tutte le connessioni in entrata e esercizi i descrittori su una struttura di dati (es .: unqueue
). Quindi ogni thread è in grado di ottenere un file dalla coda. - Accetta() è chiamato direttamente da ogni thread. (Consigliato in Unix Network Programming V1)
Problemi trovo a ciascuno di loro:
- La struttura dati statica che memorizza tutti i FD del devono essere bloccato (
mutex_lock
) prima che un thread può leggere da esso, quindi nel caso in cui un numero considerevole di thread voglia leggere nello stesso momento , non so quanto tempo passerebbe fino a quando tutti loro otterrebbero il loro obiettivo. - Ho letto che il problema relativo al Thundering Herd simultanei
accept()
chiamate non è stato completamente risolto su Linux ancora, così forse avrei bisogno di creare una soluzione artificiale ad esso che finirebbe per rendere l'applicazione almeno altrettanto lento come con l'approccio 1.
Fonti:
(Alcuni link a parlare di approccio 2: does-the-thundering-herd-problem-exist-on-linux-anymore - e un articolo che ho trovato abo ut esso (obsoleto): linux-scalability/reports/accept.html
E un SO rispondere che raccomanda approccio 1: can-i-call-accept-for-one-socket-from-several-threads-simultaneously
Sono molto interessato sulla questione, in modo da apprezzerò alcuna opinione a questo proposito :)
Grazie per l'idea della variabile di condizione, penso che possa rendere l'approccio abbastanza efficiente. Ad ogni modo vorrei sapere se il secondo approccio potrebbe essere fattibile o meno (solo per dissipare alcuni dei miei dubbi). (P.S.: Al momento non accetterò la tua risposta perché mi piacerebbe avere le opinioni di altre persone :)) – Str1101
Il secondo approccio dovrebbe essere di rigore per qualsiasi implementazione di coda che scrivi per questo scenario comunque. Se non si utilizza un condvar interno alla coda, i thread client vengono ridotti al polling costante per vedere se ci sono dati quando ciò che si vuole veramente è che dormano finché non c'è qualcosa da fare, cioè bloccare quando non c'è nulla nella coda leggere. – Duck