2010-05-06 13 views
5

Sto progettando il loop di eventi per il socket socket asincrono usando epoll/devpoll/kqueue/poll/select (incluso windows-select).Progettazione e problemi del ciclo di eventi asincroni

ho due opzioni di esecuzione, funzionamento IO:

modalità

non bloccante, sondaggio su EAGAIN

  1. Imposta presa alla modalità non-blocking.
  2. Lettura/scrittura sul socket.
  3. Se l'operazione riesce, inviare la notifica di completamento al ciclo di eventi.
  4. Se ottengo EAGAIN, aggiungere socket a "select list" e polling socket.

modalità Polling: sondaggio e quindi eseguire

  1. presa Aggiungi per selezionare lista e polling esso.
  2. aspettare la notifica che è scrivibile leggibile
  3. lettura/scrittura
  4. messaggio di notifica di completamento al ciclo di eventi di sucseeds

A me sembra che prima avrebbe richiesto meno chiamate di sistema quando si utilizza in modalità normale , in particolare per scrivere sul socket (i buffer sono abbastanza grandi). Sembra anche che sarebbe possibile ridurre il sovraccarico sul numero di "select" esecuzioni, in particolare è bello quando non si ha qualcosa che si adatta bene come epoll/devpoll/kqueue.

Domande:

  • Ci sono dei vantaggi del secondo approccio?
  • Ci sono problemi di portabilità con operazioni non bloccanti su socket/descrittori di file su numerosi sistemi operativi: Linux, FreeBSD, Solaris, MacOSX, Windows.

Note: Si prega di non suggeriscono usando implementazioni evento-loop/presa-API

risposta

3

Non sono sicuro che ci sia alcun problema di cross-piattaforma esistente; al massimo dovresti usare l'API di Windows Sockets, ma con gli stessi risultati.

In caso contrario, sembra che si stia eseguendo il polling in entrambi i casi (evitando di bloccare le attese), quindi entrambi gli approcci sono soddisfacenti. Finché non ti metti in una posizione da bloccare (ad esempio, leggi quando non ci sono dati, scrivi quando il buffer è pieno), non fa alcuna differenza.

Forse il primo approccio è più facile da codificare/capire; quindi, vai con quello.

Potrebbe essere di interesse per voi per controllare la documentazione di libev e il c10k problem per idee/approcci interessanti su questo argomento.

2

Il primo progetto è il Proactor Pattern, il secondo è il Reactor Pattern

Un vantaggio del modello del reattore è che è possibile progettare l'API in modo tale che non si dispone di allocare i buffer di lettura fino a quando i dati sono effettivamente lì da leggere Ciò riduce l'utilizzo della memoria mentre stai aspettando l'I/O.

+0

Non vedo alcun motivo per cui non si può attendere per allocare memoria un fino al bisogno di usare il primo approccio. Mi sto perdendo qualcosa? – Ioan

+2

Suppongo di sì ma in pratica non è implementato in questo modo. Nel primo caso è necessario il buffer disponibile dai passaggi 2-4, nel secondo è necessario solo nel passaggio 3. – karunski

1

dalla mia esperienza con bassa latenza applicazioni di socket:

per scrive - cercare di scrivere direttamente nella presa dalla scrittura discussione (è necessario ottenere mutex ciclo di eventi per questo), se scrittura è incompleta iscriversi scrivere prontezza con ciclo di eventi (selezionare/WaitForMultipleObjects) e scrivere a partire da fili ciclo di eventi quando tronchetto, scrivibile

per letture - essere sempre "sottoscritto" per la lettura disponibilità per tutte le prese, in modo che sempre leggere dal di dentro evento filo ciclo quando il tronchetto leggibile

Problemi correlati