2012-06-02 6 views
3

поэтому у меня проблема с потоками. Я включил пример, похожий на тот, с которым я сталкиваюсь в своей программе. Когда я запустил следующий код, он будет печатать только «привет» после нажатия кнопки «Выход» в меню. Кажется, он зависает на subprocess.call(). Я не понимаю, что происходит не так!Python Threading и подпроцессы

Кроме того, у меня нет опыта работы с потоками в 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() 

EDIT: Я забыл упомянуть, если добавить sys.stdout.write() перед subprocess.call(), то sys.stdout.write() будет работать, но subprocess.call() не будет.

+0

попробуйте установить daemon = 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

Смежные вопросы