Come gestire la multielaborazione di librerie che generano già processi secondari?

2

Ho qualche problema a trovare una buona soluzione per limitare i processi secondari in uno script che utilizza una libreria multi-elaborata e lo script stesso è anche multi-elaborato.

Entrambi, la libreria e lo script sono modificabili da noi.

Credo che la domanda sia più sul design che sul codice reale, ma per quello che vale, è scritto in Python.

L'obiettivo della biblioteca è nascondere i dettagli di implementazione di vari router Internet. Per questo motivo, la libreria ha un metodo di fabbrica "Proxy" che prende come parametro l'IP di un router. La fabbrica quindi sonda il dispositivo utilizzando una serie di possibili proxy. Di solito, c'è un proxy che sa immediatamente che è in grado di inviare comandi a questo dispositivo. Tutti gli altri di solito richiedono un po 'di tempo per tornare (dato un timeout).

Un pensiero era già solo per interrogare il dispositivo per un identificatore, e quindi selezionare il proxy appropriato usando quello, ma per farlo, avresti già bisogno di sapere come interrogare il dispositivo. L'astrazione di questa conoscenza è uno degli scopi principali della libreria, in modo che diventi un "requisito circolare" / deadlock: per connettersi a un dispositivo, è necessario sapere quale proxy utilizzare e sapere quale proxy crea, è necessario connettersi a un dispositivo.

Quindi il sondaggio del dispositivo è - come possiamo vedere - la soluzione migliore finora, oltre a tenere da qualche parte una tabella di ricerca.

La libreria uccide attualmente tutti i processi rimanenti dopo che è stato trovato un proxy valido. E sì, c'è sempre solo un buon proxy per dispositivo.

Attualmente ci sono circa 12 proxy. Quindi, se si crea un'istanza proxy usando la fabbrica, vengono generati 12 processi secondari.

Finora, questo è stato davvero utile e ha funzionato molto bene. Ma recentemente qualcun altro ha voluto utilizzare questa libreria per "trasmettere" un comando a tutti i dispositivi. Così ha preso la biblioteca e ha scritto il proprio script multi-elaborato. Questo ovviamente ha generato 12 * n processi in cui n è il numero di IP a cui ha trasmesso.

Questo ci ha dato due problemi:

  1. L'host su cui è stato eseguito il comando è rallentato fino a fermarsi.
  2. Interrompendo lo script con CTRL + C , il sistema viene fermato completamente. Nemmeno la console hardware ha risposto più! Ciò potrebbe essere dovuto ad alcune stranezze di Python che devono ancora essere investigate. Forse correlato al link

La grande domanda di fondo , è come progettare una libreria che esegue multielaborazioni, quindi altre applicazioni che usano questa libreria e vogliono essere multi-elaborate non si imbattono in limitazioni di sistema.

Il mio primo pensiero è stato quello di richiedere il passaggio di un pool alla libreria e l'esecuzione di tutte le attività in quel pool. In questo modo, la persona che utilizza la libreria ha il controllo sull'utilizzo delle risorse di sistema. Ma il mio istinto mi dice che deve esserci una soluzione migliore.

Dichiarazione di non responsabilità: la mia esperienza con il multiprocessing è piuttosto limitata. Ho implementato alcuni semplici che non richiedevano il controllo dell'accesso alle risorse. Quindi non ho ancora nessuna esperienza pratica con semafori o mutex.

p.s.: In futuro potremmo avere abbastanza informazioni per farlo senza il sondaggio. Ma il database che conterrebbe le informazioni corrette non è ancora operativo. Inoltre, il progetto sulla multiprocessing di una libreria multiprocessata mi intriga:)

    
posta exhuma 22.10.2012 - 12:54
fonte

1 risposta

1

Ci sono molti modi per affrontare questo problema; uno di loro non è quello di astrarre la natura del problema dalla sua soluzione. Tuttavia, lascia che ti suggerisca qualcos'altro.

Caching

Utilizzando il metodo corrente, è necessario (almeno una volta) analizzare ciascun proxy per ciascun dispositivo. Tuttavia, potrebbe anche essere necessario al massimo uno ; il che significa che una volta rilevato un proxy valido, non cambierà in runtime (e anche questo è riparabile da una certa complessità aggiuntiva che controlla specificamente questo caso).

Quindi, proprio all'avvio (o in qualsiasi altra occasione applicabile), convalidi tutti i proxy e memorizzi i risultati nella cache. Quindi, la trasmissione (o qualsiasi altra richiesta pertinente) cerca il proxy nella cache.

Ovviamente, per superare il fatto che stai esaurendo il sistema, devi assicurarti che il controllo e il caching avvengano in modo realistico.

    
risposta data 22.10.2012 - 13:21
fonte

Leggi altre domande sui tag