2016-06-07 210 views
0

我試圖在Windows中運行Python中的Robocopy命令(但我對任何子進程感到好奇)。該代碼非常簡單,運行良好。它是:如何殺死在線程中啓動的子進程?

def copy(): 
    with Popen(['Robocopy', media_path, destination_path, '/E', '/mir', '/TEE', '/log+:' + log_path], stdout=PIPE, bufsize=1, universal_newlines=True) as Robocopy: 
     Robocopy.wait() 
     returncode = Robocopy.returncode 

另外,我有以下運行它在一個單獨的線程:

threading.Thread(target=copy, args=(media_path, destination_path, log_path,), daemon=True) 

不過,也有某些情況下,我想停止robocopy(類似於關閉CMD窗口如果它是從命令行運行)

有沒有一種很好的方法在Python中做到這一點?

+0

不相關:除非從管道讀取,否則不要使用'stdout = PIPE'。如果你不使用'stdout = PIPE',你可以放棄'bufsize','universal_newlines'參數。 – jfs

+0

@ J.F.Sebastian,3.3+也有'subprocess.DEVNULL',這比打開'os.devnull'簡單一點。使用'nul'可擴展與'DETACHED_PROCESS'標誌一起工作的控制檯程序的範圍,而不需要管道。具體來說,如果程序需要有效的標準句柄,則會有幫助 – eryksun

回答

1

我們在Windows上可靠地殺子過程一會兒戰鬥,最終跨越這個傳來:

https://github.com/andreisavu/python-process/blob/master/killableprocess.py 

它實現了殺死你的子流程kill()方法。我們已經有了非常好的結果。

您需要以某種方式將進程對象從線程中傳出,並從另一個線程中調用kill(),或在監視某種全局標誌時使用超時輪詢wait()

1

如果進程不啓動其他進程,然後process.kill()應該工作:

import subprocess 

class InterruptableProcess: 
    def __init__(self, *args): 
     self._process = subprocess.Popen(args) 

    def interrupt(self): 
     self._process.kill() 

我不明白爲什麼你會需要它在Windows,但你可以運行Thread(target=self._process.wait, daemon=True).start(),如果你願意的話。

如果有可能該進程可能會依次啓動其他進程,那麼您可能需要一個作業對象來終止所有後代進程。看來killableprocess.py這是suggested by @rrauenza使用這種方法(我還沒有測試過)。請參閱Python: how to kill child process(es) when parent dies?