簡體   English   中英

從python線程調用的進程繼續在關閉主進程上運行

[英]Process invoked from python thread keeps on running on closing main process

我在robocopy.exe編寫了一個Tkinter包裝器,代碼組織如下:-

Tkinter包裝器:

  • 產生一個新線程並傳遞參數,其中包括源/目標和其他參數

(注意: Queue對象也傳遞給線程,因為線程將從robocopy讀取輸出並將其放入queue ,所以主tkinter線程將保持輪詢queue並使用輸出更新Tkinter文本小部件)

代碼段

... Code to poll queue and update tk widget ...

q = Queue.Queue()
t1 = threading.Thread(target=CopyFiles,args=(q,src,dst,), kwargs={"ignore":ignore_list})
t1.daemon = True
t1.start()

線程:(在單獨的文件中)

下面是線程的代碼片段

def CopyFiles(q,src,dst,ignore=None):
    extra_args =  ['/MT:15', '/E', '/LOG:./log.txt', '/tee', '/r:2', '/w:2']
    if len(ignore) > 0:
        extra_args.append('/xf')
        extra_args.extend(ignore)
        extra_args.append('/xd')
        extra_args.extend(ignore)
    command_to_pass = ["robocopy",src, dst]
    command_to_pass.extend(extra_args)
    proc = subprocess.Popen(command_to_pass,stdout=subprocess.PIPE)
    while True:
      line = proc.stdout.readline()
      if line == '':
        break
      q.put(line.strip())

關閉tkinter應用程序時調用的代碼:-

def onQuit(self):
    global t1
    if t1.isAlive():
        pass
    if tkMessageBox.askyesno("Title", "Do you really want to exit?"):
        self.destroy()
        self.master.destroy()

問題

每當運行robocopy時,我關閉tkinter應用程序,關閉python應用程序,但robocopy.exe繼續運行。

我嘗試將線程設置為守護程序,但沒有效果。 調用onQuit方法時如何停止robocopy.exe

為簡化起見,讓我們忽略Tkinter和使用單獨線程的事實。

情況是您的應用程序生成了一個子程序來執行外部程序(此問題中為robocopy.exe ),並且您需要在某個事件發生時(當Tkinter應用程序關閉時)停止應用程序中生成的程序。這個問題)。

這需要進程間的通信機制,因此將通知事件產生的進程,並做出相應的反應。 一種常見的機制是使用OS提供的信號。

您可以向外部進程發送一個信號(SIGTERM),然后要求其退出。 假設程序對信號做出了預期的響應(大多數編寫良好的應用程序都已做出了響應),您將獲得所需的行為(該過程將終止)。

在子流程上使用終止方法會將當前平台的正確信號發送到子流程。

您需要在onQuit函數中引用子流程對象proc (從提供的代碼中,我看到onQuit是一個函數,而不是對象方法,因此它可以使用全局變量來訪問proc ),因此可以調用terminate處理方法:

def onQuit(self):
    global t1, proc
    if t1.isAlive():
        pass
    # by the way I'm not sure about the logic, but I guess this
    # below statement should be an elif instead of if
    if tkMessageBox.askyesno("Title", "Do you really want to exit?"):
        proc.terminate()
        self.destroy()
        self.master.destroy()

這段代碼假定您要在全局范圍內存儲對子流程的引用,因此您還必須修改CopyFiles

我不確定robocopy如何處理終止信號,我猜這不是我們可以控制的東西。

如果您對外部程序有更多控制權(可以修改源代碼),則可能有更多選項,例如使用stdio發送消息或使用共享內存等。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM