2015-10-28 44 views
0

運行我有一個Tkinter包裝改寫robocopy.exe,如下面示出的代碼被組織: -過程保持關於關閉主處理

Tkinter的包裝:

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

(注意:Queue object is al所以傳遞到線程,因爲線程將從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

回答

0

爲了簡化事情,我們忽略Tkinter和使用單獨線程的事實。

的情況是,你的應用程序產生一個子進程來執行外部程序(robocopy.exe在這個問題上),並且你需要從你對某個事件的應用程序停止在衍生程序(當Tkinter應用程序正在關閉這個問題)。

這需要一個進程間通信機制,因此生成的進程會被通知事件,並作出相應的反應。一個常見的機制是使用OS提供的信號。

您可以向外部進程發送一個信號(SIGTERM)並要求它退出。假設程序對預期的信號作出反應(寫得最好的應用程序會這樣做),您將獲得所需的行爲(過程將終止)。

在子過程中使用terminate方法會將當前平臺的正確信號發送到子過程。

你會需要在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處理終止信號,我猜這不是我們有任何控制。

如果您對外部程序更多的控制權(可以修改源),可能有過更多的選擇,例如使用標準輸入輸出發送郵件,或使用共享內存等

+0

事實上,我從未有過之前使用過Signals。如果你可以提供一些例子(在這種情況下指針),這將是有幫助的。我需要在Tkinter包裝器中設置signal.signal(signal.SIGTERM,sighandler)嗎?但我的suprocess已經從不同的線程產生,所以我怎麼可以與'proc'對象通信 – sarbjit

+0

我剛剛更新了一些例子的答案。如果您需要定義您的應用程序(Tkitner封裝器)在進程接收到信號時做出反應,您可以使用'signal.signal'。但在這個問題中,你的應用正在發送信號,* robocopy *是需要處理信號的人。所以'signal.signal'沒有幫助。 – farzad

+0

謝謝,實際上onQuit是一個方法(我跳過了很多代碼),實際上問題仍然存在 - 我怎樣才能將'proc'對象從線程傳遞到主應用程序,因爲'proc'是在線程和'onQuit'方法內創建的是在Tkinter包裝 – sarbjit