[Python] thread e subprocess

Daniele Varrazzo piro a develer.com
Mer 29 Ott 2014 17:13:51 CET


On 2014-10-29 15:47, Antonio Conte wrote:
> * 29/10/2014, Daniele Varrazzo wrote :

>> Un modo di coordinarsi piu` robusto sarebbe quello di usare 
>> Thread.join,
>> ma come avrai gia` scoperto questo ti impedirebbe di avere un output
>> graduale nel thread principale. Lo puoi usare se eviti la print nel 
>> loop
>> principale: lanci prima tutti i processi nei thread separati, poi
>> t.join() per ogni thread.
> 
> questo posso provare a farlo. ma il join lo mettersti DOPO aver 
> lanciato
> i singoli thread ? cioe' qualcosa del genere:
> 
> [CODE]
>     _ths = []
>     for k, v in clients.items():
>         for scr in v['server']:
>             _cmd = [ 'ssh', '%s@%s' % (k, v['host'],),
>                 '"/Users/%s/bin/%s_%s.command"' % (k, k, scr,) ] + 
> _extra_params
> 
>             _ths.append(thr.Thread(target=run_command, args=(qq, 
> _cmd)))
>             _ths[-1].start()
> 
>     for _th in _ths:
>         _th.join()
> [/CODE]

Esatto: prima lanci tutti i thread, poi li joini tutti. Se li joinassi 
nel for otterresti un'esecuzione serializzata (lanci un thread e poi 
aspetti finisca). Se un thread termina prima del join non fa niente: in 
questo caso join() non blocca.


>> Nel tuo codice, qq.task_done() non credo ti serva a niente: quello 
>> serve
>> se es. il thread principale chiamasse qq.put() e poi qq.join() ed 
>> avessi
>> un pool di worker thread che chiamassero qq.get() e qq.task_done():
> 
> ah ok ! ho letto malissimo io :-|
> 
>> cosi' potresti avere es. un pool di workers a lavoro in round-robin
>> sulla coda dei compiti (es. 10 processi a lavoro su 100 compiti). Tu
>> invece hai un mapping 1-1 tra processi e compiti e solo una coda di
>> risultati: la tua struttura e' piu' semplice ma probabilmente scala
>> peggio: se avessi 1000 compiti da fare la tua macchina non sarebbe 
>> molto
>> felice di lanciare 1000 thread + 1000 processi tutti insieme.
> 
> tieni conto che sono degli script da lanciare ogni 10/15 minuti su dei
> Mac (con un lock in locale che impedisce di lanciare piu' volte lo
> script) quindi niente di trascendentale.

Io ne posso pure tenere conto :) Ti spiego solo che finche' l'input e` 
contenuto il programma ancora ancora funziona, ma resta uno script che a 
fronte di un input di dimensioni impreviste avrebbe un'occupazione 
illimitata di risorse. Sta a te "tenerne conto" :) Se hai gli elementi 
per essere sicuro che "non succedera` maimaimaimai" puoi tenerlo com'e`, 
oppure puoi renderlo robusto a fronte di imprevisti (e imparare a 
coordinare un pool di workers con una queue, che e' un pattern molto 
utile).

> cmq adesso ci provo a fare le correzioni che hai detto, e se ho altre
> domande mi faccio risentire.
> 
> grazie mille per le spiegazioni !

Di niente, a presto

-- Daniele


Maggiori informazioni sulla lista Python