2

我正在制作一个使用 python 监听套接字的应用程序。我已经通过规范使用了 Quickly(它使用 glade 和 gi.repository 来制作 gui)。但是我无论如何都无法创建线程来监听功能。即使使用线程类和 threading.Thread 类,我也尝试了很多方法。我是 Quickly 和线程的新手。我在互联网上尝试了一切:-)但找不到任何解决方案。当我使用 thread.start() 时,它会等到 gui 关闭。当我使用 thread.run() 时,它会退出 gui 并立即运行使 gui 没有响应的函数。下面是我用于线程类的示例代码。如果需要,我可以上传整个文件,因为这是一个开源项目。请帮我。

def listen(self):
    print "working"
#listen to any incoming connections
    #self.control_sock_in.listen(1)
    i=0
    while True:
        print "it works"
    #conn,addr = self.control_sock_in.accept()
    #data = conn.recv
    #if there is any incoming connection then check for free slot and reply with that free slot
#if change of status message then update nodelist

def on_btn_create_n_clicked(self, widget):
    self.btn_quit_n.set_sensitive(True)
    self.btn_join_n.set_sensitive(False)
    self.btn_create_n.set_sensitive(False)
    subprocess.check_call(["sudo", "ifconfig", "wlan0", "192.168.0.5", "netmask", "255.255.255.0", "broadcast", "192.168.0.255"])
    self.control_sock_in = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    self.control_sock_in.bind(('192.168.0.5', 6000))
    self.status_lbl.set_text("Created the network successfully with IP of 192.168.0.5!")
    self.nodelist['192.168.0.5'] = ('6000','0')
#start thread on listen()  
    thread.start_new_thread(self.listen,(self,))
    self.btn_camera.set_sensitive(True)
    self.btn_mixer.set_sensitive(True)
    self.btn_display.set_sensitive(True)

顺便说一句,无需为我提供注释项的缺失代码。我可以做到。我坚持的是线程问题。

4

2 回答 2

2

你可以像那样简单地做到这一点

from threading import Thread
listener_thread = Thread(target=self.listen)
listener_thread.start()

当您的程序终止并且有一些非守护线程正在运行时,它将等待它们全部完成。

您可以将您的线程标记为daemon,但您需要小心它们 - 请参阅本文了解更多详细信息。基本上,由于其他线程中正在发生或已经发生的清理,它们可能仍在运行并使用处于一致状态的数据。

创建守护线程:

from threading import Thread
listener_thread = Thread(target=self.listen)
listener_thread.daemon = True 
# or listener_thread.setDaemon(True) for old versions of python
listener_thread.start()

最好的选择是让您的侦听器线程保持非守护程序(默认),并想办法在您的程序即将退出时以某种方式通知侦听器线程。因此,您的侦听器线程可以优雅地完成。

更新

不要使用run线程对象的方法 - 它只是调用您在当前调用它的线程中指定的函数。调用对象的start方法Thread会在单独的线程中触发您的活动。

于 2012-12-04T11:46:28.350 回答
0

好吧,我在这里找到了解决方案。来自 askubuntu 的链接 必须在开头添加这两行 from gi.repository import GObject, Gtk GObject.threads_init()

无论如何,非常感谢 Michael Hall 在快速 IRC 频道中指出我的问题。

于 2012-12-07T15:42:18.600 回答