2012-06-02 114 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