In un primo momento, devo chiedere quale sia il migliore in quali stati? Ad esempio un server MMORPG in tempo reale. Cosa succede se creo un thread per client invece di utilizzare socket non bloccanti? O cosa succede se uso un thread che contiene tutti i socket non bloccanti? Puoi spiegarmi i vantaggi?Perché dovrei usare socket non bloccanti o bloccanti?
risposta
Questa domanda merita una discussione più lungo ma ecco un breve pugnalata a una risposta:
- socket bloccanti significa che una sola presa può essere attivo in qualsiasi momento in qualsiasi filo (perché blocca durante l'attesa per l'attività)
- socket bloccanti è generalmente più facile che non bloccanti (programmazione asincrona tende ad essere più complicato)
- si potrebbe creare 1 thread per presa come indicato ma fili hanno testa e sono estremamente inefficiente rispetto agli soluzioni non bloccanti;
- con prese non-blocking si potrebbe gestire un volume molto più grande di clienti: potrebbe scalare a centinaia di migliaia in un singolo processo - ma il codice diventa un po 'più complicata
Con i socket non bloccanti (su Windows) si dispone di un paio di opzioni:
- polling
- eventi basati
- I sovrapposta/O
I/O sovrapposti offrono le migliori prestazioni (migliaia di socket/processo) a scapito del modello più complicato da comprendere e implementare correttamente.
Fondamentalmente si tratta di prestazioni e complessità di programmazione.
NOTA
Ecco una migliore spiegazione del perché si utilizza un modello di thread/presa è una cattiva idea:
In Windows, la creazione di un gran numero di thread è altamente inefficiente, perché lo scheduler è in grado di determinare correttamente quali thread devono ricevere il tempo del processore e quali no. Ciò, unito al sovraccarico della memoria di ciascun thread, significa che si esauriranno la memoria (a causa dello spazio di stack) e i cicli del processore (a causa dell'overhead nella gestione dei thread) a livello di sistema operativo molto prima che si esaurisca la capacità di gestire le connessioni socket .
Andrò a verbale dicendo che per quasi qualsiasi cosa eccetto i programmi giocattolo, è necessario utilizzare socket non bloccanti come una cosa ovvia.
Le prese di blocco causano un problema grave: se la macchina all'altra estremità (o qualsiasi parte della connessione ad essa) non riesce durante una chiamata di blocco, il codice finirà bloccato fino al timeout dello stack IP. In un caso tipico, sono circa 2 minuti, il che è completamente inaccettabile per la maggior parte degli scopi. L'unico modo in per interrompere la chiamata di blocco è terminare il thread che lo ha prodotto, ma terminare un thread è quasi sempre inaccettabile, in quanto è praticamente impossibile ripulirlo e recuperare le risorse assegnate.Gli zoccoli non bloccanti rendono banale l'interruzione di una chiamata quando/se necessario, senza facendo qualcosa al thread che ha effettuato la chiamata.
È possibile eseguire prese di blocco con una sorta di pozzo se si utilizza invece un modello multi-processo. Qui, si genera semplicemente un processo completamente nuovo per ogni connessione. Quel processo usa un socket di blocco, e quando/se qualcosa va storto, basta uccidere l'intero processo. Il sistema operativo sa come ripulire le risorse da un processo, quindi la pulizia non è un problema. Tuttavia ha ancora altri potenziali problemi: 1) è necessario un monitor di processo per uccidere i processi quando necessario, e 2) generare un processo è in genere un po 'più costoso della semplice creazione di un socket. Tuttavia, questo può essere una valida opzione, soprattutto se:
- Hai a che fare con un piccolo numero di connessioni alla volta
- È generalmente svariati processi di lavorazione per ogni connessione
- Hai a che fare solo con ospiti locali in modo che il collegamento a loro è veloce e affidabile
- Sei più interessato a ottimizzare lo sviluppo di esecuzione
1. Beh, tecnicamente non è il modo solo possibile, ma la maggior parte delle alternative sono relativamente brutte - per essere più specifici, penso che quando aggiungerai il codice per capire che c'è un problema, e poi risolvi il problema, probabilmente hai fatto più lavoro extra rispetto a quando usi un socket non bloccante.
È possibile interrompere un'operazione socket bloccata senza terminare il thread bloccato disconnettendo il socket da un altro contesto di thread. Ciò causerà il fallimento dell'operazione bloccata con un codice di errore, quindi il thread bloccato può spostarsi e fare altre cose, come la normale pulizia. –
- 1. recvfrom() errore 10035 utilizzando socket non bloccanti
- 2. Come posso ottenere socket non bloccanti connect()?
- 3. Play Framework: caricamenti di file - bloccanti o non bloccanti?
- 4. Letture file non bloccanti
- 5. Come gestire OpenSSL SSL_ERROR_WANT_READ/WANT_WRITE su socket non bloccanti
- 6. select(), recv() e EWOULDBLOCK su socket non bloccanti
- 7. Celery + Eventlet + richieste non bloccanti
- 8. Obsession con script non bloccanti
- 9. Rails: richieste HTTP non bloccanti?
- 10. Lettura due iteratori bloccanti
- 11. È possibile eseguire pubub Redis non bloccanti?
- 12. Scrittura di applicazioni PHP non bloccanti
- 13. SwapBuffers non bloccanti() con VSync = on
- 14. Zoccoli non bloccanti: i messaggi sono in coda?
- 15. Informazioni su NodeJS e non bloccanti IO
- 16. Come creare metodi non bloccanti in Scala?
- 17. Blocchi di blocco contro blocchi non bloccanti
- 18. Esecuzione di richieste non bloccanti? - Django
- 19. jQuery chiamate ajax sincroni non bloccanti
- 20. Qual è il vantaggio dell'utilizzo di socket non bloccanti con la funzione "select"?
- 21. AsyncHttpClient può eseguire chiamate HTTP asincrone e non bloccanti?
- 22. Perché non dovrei usare Unity?
- 23. Come scrivere su un file usando IO non bloccanti?
- 24. Come eseguire query MySQL asincrone/non bloccanti in Play framework?
- 25. Perché non dovrei usare atoi()?
- 26. Perché dovrei usare glBindAttribLocation?
- 27. C# socket non bloccante senza loop (vero)
- 28. Perché dovrei usare gitignore?
- 29. Perché dovrei usare Drools?
- 30. Perché non dovrei usare uguali con ereditarietà?
Se si sta eseguendo su una scatola di 80 modo, si può strappare centinaia di fili non è un problema. –
@John - Solo perché è possibile creare centinaia di thread (se hai abbastanza memoria) non significa che sia una buona idea. In effetti è una cattiva idea! –
Il mio punto, certamente non ben fatto, è che non si può semplicemente tracciare una linea arbitraria a 20 e chiamare qualsiasi numero di thread oltre quel "cattivo". –