Domanda

Recentemente ho bisogno di scrivere uno script che esegue un os.fork () di dividere in due processi. Il processo bambino diventa un processo server e passa dati al processo genitore con un tubo creata con os.pipe () . Il bambino chiude l''r' estremità del tubo e il genitore chiude l''w' estremità del tubo, come al solito. Converte i rendimenti da pipe () in oggetti di file con os.fdopen .

Il problema che sto avendo è questo: Il processo con successo forchette, e il bambino diventa un server. Tutto funziona alla grande e il bambino scrive diligentemente i dati all'aperto read() estremità del tubo. Purtroppo la fine genitore del tubo fa due cose strane:
A) Si blocca sull'operazione <=> sulla <=> estremità del tubo.
In secondo luogo, non riesce a leggere i dati che è stato messo sul tubo a meno che il <=> estremità è interamente chiuso.

Ho subito pensato che il buffering era il problema e ha aggiunto pipe.flush) (chiamate, ma questi non ha aiutato.

Qualcuno può far luce sul motivo per cui i dati non appare fino alla fine di scrittura sia completamente chiuso? E c'è una strategia per rendere il <=> non bloccante chiamata?

Questo è il mio primo programma Python che biforcuta o tubi utilizzati, quindi perdonatemi se ho fatto un semplice errore.

È stato utile?

Soluzione

Stai usando read () senza specificare una dimensione, o trattare il tubo come un iteratore (for line in f)? Se è così, questo è probabilmente la causa del problema - read () è definito a leggere fino alla fine del file prima di ritornare, piuttosto che leggere quello che è disponibile per la lettura. Ciò significa che bloccherà fino a quando il bambino chiama close ().

Nel codice di esempio legato a, questo è OK - il genitore si comporta in un modo di blocco, e usando solo il bambino a fini di isolamento. Se si desidera continuare, quindi utilizzare non-blocking IO come nel codice che avete inviato (ma essere pronti a trattare con i dati semi-completo), o leggere in blocchi (ad esempio r.read (dimensione) o r.readline () ) che blocca solo fino ad una determinata taglia / linea è stato letto. (Avrai ancora bisogno di chiamare a filo sul bambino)

Si presenta come trattare il tubo come un iteratore sta usando qualche ulteriore buffer come pure, per "for line in r:" non può dare quello che vuoi se hai bisogno di ogni riga per essere immediatamente consumato. Potrebbe essere possibile disattivare questo, ma solo specificando 0 per la dimensione del buffer in fdopen non sembra sufficiente.

Ecco alcuni esempi di codice che dovrebbe funzionare:

import os, sys, time

r,w=os.pipe()
r,w=os.fdopen(r,'r',0), os.fdopen(w,'w',0)

pid = os.fork()
if pid:          # Parent
    w.close()
    while 1:
        data=r.readline()
        if not data: break
        print "parent read: " + data.strip()
else:           # Child
    r.close()
    for i in range(10):
        print >>w, "line %s" % i
        w.flush()
        time.sleep(1)

Altri suggerimenti

con

fcntl.fcntl(readPipe, fcntl.F_SETFL, os.O_NONBLOCK)

Prima di invocare il read () risolto entrambi i problemi. La chiamata read () non sta bloccando ei dati vengono visualizzati dopo appena un flush () sul lato di scrittura.

Vedo che hai risolto il problema del blocco di I / O e il buffering.

Una nota, se si decide di provare un approccio diverso: il sottoprocesso è l'equivalente / un sostituto per il linguaggio fork / exec. Sembra che questo non è quello che stai facendo: basta un bivio (non un exec) e lo scambio di dati tra i due processi - in questo caso la multiprocessing modulo (in Python 2.6 +) sarebbe una misura migliore.

Il "padre" vs. parte "figlio" di forchetta in un'applicazione Python è sciocco. Si tratta di un lascito da 16 bit giorni unix. E 'un vezzo da un giorno in cui fork / exec e exec erano cose importanti per rendere la maggior parte di un piccolissimo processore.

Rompere il vostro codice Python in due parti distinte:. Genitore e figlio

La parte genitore dovrebbe usare sottoprocesso per eseguire la parte del bambino.

Una forcella e exec può accadere in qualche luogo in là - ma non c'è bisogno di preoccuparsi

.
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top