2009-09-16 17 views

risposta

18

Sì, questo è ciò che è socket_set_nonblock(). Il codice di interazione del socket dovrà essere scritto in modo diverso, tenendo conto dei significati speciali che assumono i codici di errore 11, EWOULDBLOCK e 115, EINPROGRESS.

Ecco alcuni esempi di codice in qualche modo-romanzata da un PHP sincronizzazione ciclo presa di polling, come richiesto:

$buf = ''; 
$done = false; 
do { 
    $chunk = socket_read($sock, 4096); 
    if($chunk === false) { 
     $error = socket_last_error($sock); 
     if($error != 11 && $error != 115) { 
      my_error_handler(socket_strerror($error), $error); 
      $done = true; 
     } 
     break; 
    } elseif($chunk == '') { 
     $done = true; 
     break; 
    } else { 
     $buf .= $chunk; 
    } 
} while(true); 
+0

Cosa intendi in modo diverso? Puoi mostrarmi qualche esempio di codice di eventi ricevuti da dati asincroni? –

+0

Quindi questo è sincrono, ma non bloccante? Quindi cosa significa esattamente non-bloccante? –

+3

No, è asincrono e basato su polling. Il codice proviene da un meccanismo di polling più ampio. PHP non ha supporto per gli eventi I/O del socket basati su interrupt/segnale come richiesto, per quanto ne so. Si ottengono comunicazioni asincrone utilizzando operazioni che non attendono il completamento ma restituiscono immediatamente, con un codice di errore indicativo, se l'operazione non è pronta. Come legge su un socket non bloccante. Ci sono molti tutorial sull'uso del socket asincrono in C che andranno in molti dettagli su questo; Il supporto di PHP è solo uno strato rispetto alla roba C standard. – chaos

0

AFAIK PHP è strettamente singlethreaded, che significa che non si può fare questo in modo asincrono, perché l'esecuzione di script è sempre lineare.

È passato un po 'di tempo da quando l'ho fatto, ma per quanto ricordo, è possibile solo aprire il socket e fare in modo che lo script continui l'esecuzione alla ricezione dei dati.

+0

Anche il codice di codice del caos sembra confermare questo fatto. –

+1

PHP fornisce stream_select per le operazioni di socket asincrono, analogamente a posix select(). – karunski

+1

select() è sincrono: consente solo di sapere se un socket è pronto per la lettura/scrittura. Si chiama ancora da un singolo thread e si blocca sulla chiamata select() invece che read() o write(). –

5

Come si esegue lo stesso in modo asincrono? così posso rispondere ai dati in un evento di dati ricevuti, invece di polling per i dati , ecc

Sarà necessario eseguire lo script ed emettere stream_select controllare weither v'è alcun dato per ricevere. Elabora e invia i dati indietro.

5

Il termine "asincrono" viene spesso utilizzato in modo errato nella programmazione di rete. Per I/O, asincrono viene spesso usato come un'altra parola per non bloccare. Ciò significa che il processo è in grado di continuare prima che una chiamata sulla rete abbia completato la trasmissione.

Per l'esecuzione del processo in generale, asincrono significa che più istruzioni possono essere calcolati contemporaneamente (contemporaneamente.)

In altre parole, I/O asincrono non è veramente asincrono meno più thread vengono utilizzati per consentire multiplo reads/write/accetta che si verifichi simultaneamente - tutti i socket dovranno attendere una chiamata sincrona non bloccante se ha dati da leggere/scritti o altrimenti non bloccherà, e leggere/scrivere un file di grandi dimensioni può richiedere ancora secondi o anche minuti se non interrotti. Si noti che ciò richiederebbe un flusso perfetto tra client e server o TCP stesso interromperà la trasmissione. Ad esempio, un server che invia più velocemente di un client può scaricare causerebbe un blocco su una scrittura.

Quindi da un punto di vista rigoroso, PHP non è in grado di eseguire il networking asincrono, solo non bloccante. In breve, la progressione del processo si interrompe mentre la chiamata di rete è in grado di leggere/scrivere utilmente, ecc. Tuttavia, il processo continuerà quando la chiamata non è in grado di leggere/scrivere utilmente o altrimenti bloccherebbe. In un sistema veramente asincrono, il processo continuerà a prescindere e la lettura/scrittura verrà eseguita in un thread diverso. Si noti che il blocco degli I/O può ancora essere eseguito in modo asincrono se eseguito in un thread diverso.

Inoltre, PHP non è in grado di eseguire l'I/O guidato da eventi senza installare un'estensione che lo supporta. Dovrai altrimenti eseguire una qualche forma di polling per eseguire I/O non bloccanti in PHP. Il codice da Chaos sarebbe un esempio di lettura non bloccante funzionale se usasse socket_select.

Con ciò detto, la funzione di selezione consentirà comunque il vero comportamento non bloccante in PHP. In C, i servizi di polling hanno una perdita di prestazioni rispetto agli eventi, quindi sono sicuro che sarebbe lo stesso per PHP. Ma questa perdita è in nanosecondi-microsecondi a seconda della quantità di socket, in cui il tempo risparmiato da una chiamata non bloccante è in genere millisecondi o anche secondi se la chiamata viene fatta attendere.

Problemi correlati