2012-06-02 113 views
3

所以我遇到線程問題。我已經加入了一個類似於我在我的程序中遇到的例子。當我運行下面的代碼時,在按下菜單中的「退出」按鈕後,它只會打印「你好」。它似乎掛在subprocess.call()上。我不明白髮生了什麼問題!Python線程和子進程

另外,我沒有使用Python進行線程化的經驗,而且我對整個語言都很陌生,因此隨時大聲疾呼我的結構缺陷以及Python編程慣例! :)

謝謝!

import threading 
import subprocess 

import gtk 

class TestDaemon: 
    def __init__(self): 

     # start thread here 
     cmdman = CommandManager() 
     threading.Thread(target=cmdman.run, args=('CmdThread', 1)).start() 

     self.icon = gtk.StatusIcon() 
     self.icon.set_from_stock(gtk.STOCK_ABOUT) 
     self.icon.set_visible(True) 

     self.menu = gtk.Menu() 
     self.menu_item = gtk.ImageMenuItem(gtk.STOCK_QUIT) 
     self.menu_item.connect('activate', self.quit_app, self.menu) 
     self.menu.append(self.menu_item) 

     self.icon.connect('popup-menu', self.popup_menu, self.menu) 
     self.icon.set_visible(True) 

     gtk.main() 

    def quit_app(self, widget, data = None): 
     gtk.main_quit() 

    def popup_menu(self, widget, button, time, data = None): 
     if button == 3 and data: 
      data.show_all() 
      data.popup(None, None, gtk.status_icon_position_menu, 
         3, time, self.icon) 

class CommandManager: 
    def __init__(self): 
     pass 

    def run(self, *args): 
     subprocess.call('echo "hello"', shell=True) 

if __name__ == '__main__': 
    TestDaemon() 

編輯: 我忘了提,如果我的subprocess.call(前添加sys.stdout.write函數()),該sys.stdout.write函數()將運行,但subprocess.call () 將不會。

+0

嘗試在您正在產卵的線程上設置守護程序= True,或在退出之前加入它。 –

+0

非常好,謝謝!加入它是我所需要的! :) – kotakotakota

+0

介意如果我把這個作爲答案? #reputation_whoring –

回答

3

(張貼評論最初):

加入線程退出前:

class TestDaemon: 
    def __init__(self): 

     # start thread here 
     cmdman = CommandManager() 
     self.cmdThread = threading.Thread(target=cmdman.run, args=('CmdThread', 1)) 
     self.cmdThread.daemon = True 
     self.cmdThread.start() 

     ... 

    def quit_app(self, widget, data = None): 
     self.cmdThread.join() 
     gtk.main_quit() 

設置線程守護進程是主線程提出了一些異常,並且加入的情況下()不叫。

+0

再次感謝!不幸的是,由於我的聲譽仍然太低,我無法對其進行+1。 – kotakotakota

0

你應該使用gtk.mainloop()而不是gtk.main()那麼它應該工作。

這裏的問題是,gtk.main()塊,並不讓其他線程運行,它可能不會釋放GIL。

+0

感謝您的建議,但它沒有工作...... :(任何其他想法? – kotakotakota

+0

什麼不工作?如果我運行[你的程序與mainloop而不是main](http://pastie.org/4015598 )(並將該呼叫移出課程,因爲它不應該屬於該課程),它按預期工作。 – mata

+0

無論出於何種原因,它似乎每隔一段時間都會起作用,但其他時間,它不會......(也就是說,如果我連續運行它一段時間,它會按預期不時運行。) – kotakotakota