![](/img/trans.png)
[英]python multiprocessing.Process.terminate - How to kill child processes
[英]How can I kill a parent from a child process using multiprocessing in Python and Windows?
我想在其中一個子進程到達特定點時結束我的腳本。 假設我有以下代碼:
import multiprocessing
import time
import sys
def another_child_process (my_queue):
time.sleep(3)
my_queue.put("finish")
def my_process(my_queue):
while True:
if my_queue.empty() is False:
my_queue.get()
print("Killing the program...")
### THIS IS WHERE I WANT TO KILL MAIN PROCESS AND EXIT
sys.exit(0)
def main():
## PARENT PROCESS WHICH I WANT TO KILL FROM THE CHILD
my_queue = multiprocessing.Queue()
child_process = multiprocessing.Process(target=my_process, args=(my_queue,))
another_process = multiprocessing.Process(target=another_child_process, args=(my_queue,))
child_process.start()
another_process.start()
while True:
pass ## I want to end the program in the child process
if __name__=="__main__":
main()
我讀過一些關於使用信號的東西,但它們主要用於 Linux,我不太清楚如何在 Windows 中使用它們。 實際上,我是 Python 的初學者。 我怎樣才能完全結束腳本?
首先,如果你仔細閱讀文檔,你會發現在multiprocessing.Queue
上調用is_empty
方法是不可靠的,不應該使用。 此外,你有一個競爭條件。 也就是說,如果my_process
在another_child_process
之前運行(並且假設is_empty
是可靠的),它會發現隊列為空並提前終止,因為another_child_process
還沒有機會將任何項目放入隊列。 所以你應該做的是讓another_child_process
將它想要的任何消息放在隊列中,然后放置一個額外的哨兵項目,其目的是表明沒有更多的項目將被放入隊列。 因此,哨兵用作准文件結束指示器。 您可以使用任何不同的對象作為哨兵,只要它不能被視為“真實”數據項。 在這種情況下,我們將使用None
作為哨兵。
但是您編寫的實際示例並不是一個實際示例,說明為什么您需要一些特殊機制來終止主進程並退出,因為一旦another_process
將其項目放入隊列中,它就會返回並因此進程終止並且一旦my_process
檢測到它已經從隊列中檢索了所有項目並且將不再有,它返回並因此其進程終止。 因此,主進程所要做的就是發出一個調用以join
兩個子進程並等待它們完成然后退出:
import multiprocessing
import time
import sys
def another_child_process (my_queue):
time.sleep(3)
my_queue.put("finish")
my_queue.put(None)
def my_process(my_queue):
while True:
item = my_queue.get()
if item is None:
break
print('Item:', item)
def main():
## PARENT PROCESS WHICH I WANT TO KILL FROM THE CHILD
my_queue = multiprocessing.Queue()
child_process = multiprocessing.Process(target=my_process, args=(my_queue,))
another_process = multiprocessing.Process(target=another_child_process, args=(my_queue,))
child_process.start()
another_process.start()
child_process.join()
another_process.join()
if __name__=="__main__":
main()
印刷:
Item: finish
這里也許是一個更好的例子。 another_child_process
以某種方式獲取數據(出於演示目的,我們有一個生成器函數get_data
)。 如果沒有出現異常情況,它會將所有數據放入隊列中,以便my_process
跟隨None
哨兵項,以便my_process
知道沒有更多數據即將到來,它可以終止。 但是讓我們假設get_data
有可能生成一個特殊的異常數據項,即用於演示目的的字符串“finish”。 在這種情況下, another_child_process
將立即終止。 但是,此時隊列中有許多項my_process
尚未檢索和處理。 我們想強制my_process
立即終止,以便主進程可以立即join
子進程並終止。
為此,我們將一個事件傳遞給由主進程啟動的守護線程,該線程等待事件被設置。 如果事件是由another_child_process
設置的,我們也將事件傳遞給了它,線程將立即終止my_process
進程:
import multiprocessing
import time
import sys
def get_data():
for item in ['a', 'b', 'c', 'finish', 'd', 'e', 'f', 'g']:
yield item
def another_child_process(my_queue, exit_event):
for item in get_data():
if item == 'finish':
# Abnormal condition where we must exit imemediately.
# Immediately signal main process terminate:
exit_event.set()
# And we terminate:
return
my_queue.put(item)
# Normal situation where we just continue
# Put in sentinel signifying no more data:
my_queue.put(None)
def my_process(my_queue):
while True:
item = my_queue.get()
if item is None: # Sentinel?
# No more data:
break
print("Got: ", repr(item))
print('my_process terminating normally.')
def main():
import threading
def wait_for_quit(exit_event):
nonlocal child_process
exit_event.wait()
child_process.terminate()
print("Exiting because event was set.")
exit_event = multiprocessing.Event()
# Start daemon thread that will wait for the quit_event
threading.Thread(target=wait_for_quit, args=(exit_event,), daemon=True).start()
my_queue = multiprocessing.Queue()
child_process = multiprocessing.Process(target=my_process, args=(my_queue,))
another_process = multiprocessing.Process(target=another_child_process, args=(my_queue, exit_event))
child_process.start()
another_process.start()
# Wait for processes to end:
child_process.join()
another_process.join()
if __name__=="__main__":
main()
印刷:
Got: 'a'
Exiting because event was set.
如果您從get_data
返回的數據中刪除finish
消息,則所有進程將正常完成,打印的內容將是:
Got: 'a'
Got: 'b'
Got: 'c'
Got: 'd'
Got: 'e'
Got: 'f'
Got: 'g'
my_process terminating normally.
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.