Domanda

Domanda:

Posso usare il modulo multiprocessing insieme a Gevent su Windows in modo efficiente?

Scenario:

Ho un'applicazione Python basata su Gevent che esegue I/O asincrona su Windows. L'applicazione è principalmente legata all'I/O, ma ci sono anche picchi di carico CPU più elevato. Questa applicazione dovrebbe controllare un'applicazione della console tramite la sua stdin e stdout. Non riesco a modificare questa applicazione della console e l'utente sarà in grado di utilizzare il proprio personalizzato, solo il protocollo di comunicazione basato sul testo (riga) è risolto.

Ho un'implementazione funzionante utilizzando sottoprocesso e thread, ma preferirei spostare l'intero codice di comunicazione basato sul sottoprocesso insieme a quei thread in un processo separato per riportare l'applicazione principale su un thread singolo. Ho intenzione di utilizzare il modulo multiprocessing per questo.

Lettura precedente:

Ho cercato molto sul Web e ho letto un po 'di codice sorgente, quindi so che il modulo multiprocessing utilizza un'implementazione di tubi basata su tubi denominati su Windows. Una coppia di oggetti multiprocessing.queue.queue verrebbero utilizzati per comunicare con il secondo processo di Python. Queste code si basano su quell'implementazione del tubo, ad esempio l'IPC verrebbe eseguito tramite tubi nominati.

La domanda chiave è se chiamare il metodo GET della coda in arrivo bloccherebbe o meno il loop principale di Gevent. C'è un timeout per quel metodo, quindi potrei trasformarlo in un piccolo timeout, ma non è una buona soluzione, dal momento che bloccherebbe comunque Gevent per piccoli periodi di tempo che danneggiano la sua bassa latenza I/O.

Sono anche aperto a suggerimenti su come aggirare l'intero problema dell'uso di tubi su finestre, che è noto per essere difficile e talvolta fragile. Non sono sicuro se IPC basato sulla memoria condivisa sia possibile su Windows o meno. Forse potrei avvolgere l'applicazione della console in un modo che consentirebbe di comunicare con il processo figlio utilizzando le prese di rete, che è noto per funzionare bene con Gevent.

Per favore, non mettere in discussione il mio caso d'uso principale, se possibile. Grazie.

È stato utile?

Soluzione

Il metodo GET della coda sta davvero bloccando. Usarlo con il timeout potrebbe potenzialmente risolvere il tuo problema, ma sicuramente non sarà una soluzione più pulita e, che è la più importante, introdurrà latenza extra senza una buona ragione. Anche se non è stato bloccato, non sarà neanche una buona soluzione. Solo perché il non bloccante stesso non è sufficiente, la buona chiamata/API asincrona dovrebbe integrarsi senza intoppi nel framework I/O in uso. Sii quel Gevent per Python, Libevent per C o Boost ASIO per C ++.

La soluzione più semplice sarebbe quella di utilizzare l'I/O semplice generando le tue applicazioni di console e attaccando la sua console dentro e fuori i descrittori. Ci sono due principali fattori da considerare:

  • Sarà estremamente facile per i tuoi clienti scrivere applicazioni client. Non dovranno lavorare con nessun tipo di IPC, socket o altro codice, il che potrebbe essere molto difficile per molti. Con questo approccio, l'applicazione leggerà appena da stdin e scriverà a stdout.
  • Sarà estremamente facile testare le applicazioni della console utilizzando questo approccio in quanto è possibile avviarle manualmente, inserire il testo in console e vedere i risultati.
  • Gevent è perfetto per asincroni lettura/scrittura qui.

Tuttavia, il rovescio della medaglia è che dovrai avviare questa applicazione, non ci sarà supporto per la comunicazione concorrente con essa e non ci sarà alcun supporto per la comunicazione sulla rete. C'è anche un buon esempio per i principianti.

Per mantenerlo semplice ma più flessibile, è possibile utilizzare le prese TCP/IP. Se sia il client che il server sono in esecuzione sulla stessa macchina. Inoltre, un buon sistema operativo utilizzerà IPC come implementazione sottostante, quindi sarà veloce. E, se ti preoccupi delle prestazioni di questo caso, probabilmente non dovresti usare Python e guardare altre tecnologie.

Anche la soluzione fantastica: usa Zeroc ghiaccio. È una tecnologia molto moderna che consente una comunicazione tra process quasi senza soluzione di continuità. È un killer Corba, molto facile da usare. È pesantemente usato da molti, dimostrato di essere più veloce nella sua classe e rock stabile. La bellezza di questa soluzione è che puoi integrare perfettamente i programmi in molte lingue diverse, come Python, Java, C ++ ecc. Ma ciò richiederà un po 'di tempo per acquisire familiarità con un concetto. Se decidi di andare in questo modo, trascorri una giornata a leggere la documentazione.

Spero che sia d'aiuto. Buona fortuna!

Altri suggerimenti

La tua domanda è già abbastanza vecchia. Tuttavia, vorrei raccomandare http://gehrcke.de/gipc Che-credo-affronterebbe la sfida delineata in modo molto dritto. Fondamentalmente, ti consente di integrare i processi figlio basati su multiprocessing ovunque nell'applicazione (anche su Windows). Interazione con Process oggetti (come chiamare join()) è Gevent-Cooprative. Tramite la sua gestione dei tubi, consente di bloccare in modo cooperativo la comunicazione tra process. Tuttavia, su Windows, IPC è attualmente molto meno efficiente rispetto ai sistemi conformi a POSIX (poiché l'I/O non bloccante viene imitato attraverso un pool di thread). A seconda del volume di messaggistica IPC dell'applicazione, questo potrebbe o non potrebbe essere significativo.

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