Vorrei eseguire processi secondari arbitrari basati su console e gestirli da un singolo processo master. I sottoprocessi basati su console comunicano tramite stdin, stdout e stderr e, se li si esegue in una console originale, terminano in modo pulito quando si preme CTRL + C. Alcuni di essi potrebbero in effetti essere un albero di processi, come uno script batch che esegue un eseguibile che a sua volta può eseguire un altro eseguibile per fare un po 'di lavoro. Vorrei reindirizzare il loro I/O standard (ad esempio, in modo che possa mostrare il loro output in una finestra della GUI) e in determinate circostanze inviare loro un evento CTRL + C in modo che possano rinunciare e terminare in modo pulito.Invia CTRL + C per subprocess tree su Windows
I seguenti due diagrammi mostrano prima la struttura normale: un processo principale ha quattro sottoprocessi di lavoro e alcuni di questi hanno i propri sottoprocessi; e poi cosa dovrebbe accadere quando uno dei lavoratori deve essere fermato - e tutti i suoi figli dovrebbero ottenere l'evento CTRL + C, ma nessun altro processo dovrebbe ricevere l'evento CTRL + C.
Process diagram http://pics.livejournal.com/clockworksaint/pic/0007z5yr/s640x480.png
Inoltre, preferirei di gran lunga che non ci sono finestre in più visibili per l'utente.
Ecco che cosa ho provato (notare che io sto lavorando in Python, ma soluzioni per C sarebbe ancora utile):
- Deposizione un processo intermedio in più con
CREATE_NEW_CONSOLE
, e poi averlo deporre le uova la processo di lavoro. Poi chiama lo GenerateConsoleCtrlEvent (CTRL_C_EVENT
, 0) quando vogliamo uccidere il lavoratore. Sfortunatamente,CREATE_NEW_CONSOLE
sembra impedirmi di reindirizzare i canali di I/O standard, quindi non mi rimane un modo semplice per riportare l'output al programma principale. - Creazione di un processo intermedio aggiuntivo con
CREATE_NEW_PROCESS_GROUP
e successiva creazione del processo di lavoro. Poi chiama lo GenerateConsoleCtrlEvent (CTRL_C_EVENT
, 0) quando vogliamo uccidere il lavoratore. In qualche modo, questo riesce a inviare il CTRL + C solo al processo principale, che è completamente inutile. A un esame più attento, GenerateConsoleCtrlEvent dice che CTRL + C non può essere inviato ai gruppi di processi. - Generazione del sottoprocesso con
CREATE_NEW_PROCESS_GROUP
. Quindi chiama lo GenerateConsoleCtrlEvent (CTRL_BREAK_EVENT
, pid) per uccidere il lavoratore. Questo non è l'ideale, perché CTRL + BREAK è meno amichevole di CTRL + C e probabilmente si tradurrà in una conclusione più caotica. (Ad esempio, se si tratta di un processo Python, nessun KeyboardInterrupt può essere catturato e nessun blocco finale può essere eseguito.)
C'è un buon modo per fare ciò che voglio? Posso vedere che potrei teoricamente costruire al primo tentativo e trovare un altro modo di comunicare tra i processi, ma sono preoccupato che si rivelerà estremamente imbarazzante. Ci sono buoni esempi di altri programmi che ottengono lo stesso effetto? Sembra così semplice che non può essere un requisito così raro.
Ho esaminato gli oggetti di lavoro in precedenza, ma l'unico meccanismo che forniscono per arrestare il lavoro consiste nel terminare forzatamente i suoi processi. La ragione per cui voglio inviare CTRL + C è dare ai processi un'opportunità per finire in modo pulito. Nota che i gruppi di processi e CTRL_BREAK_EVENT fanno un lavoro soddisfacente se non mi interessa specificamente l'invio di un CTRL + C. – Weeble