2012-10-25 70 views
0

这是我的问题的一个小实现。当我点击“按下”按钮时,它会挂起,有些时候不是。如何克服这个悬挂? 这是我的代码。线程不能与pygtk一起工作并始终挂起

要安装理智的“sudo易于得到安装python-成像理智”

import gtk 
import gtk.glade 
import threading 
import os 
import sane 
gtk.gdk.threads_init() 
class process(threading.Thread): 
    def __init__(self,main_object): 
     self.main_object = main_object 
     threading.Thread.__init__(self) 

    def run(self): 
     sane_version = sane.init() 
     sane_devices = sane.get_devices() 
     gtk.threads_enter() 
     self.main_object.pb.set_fraction(self.main_object.value) 
     gtk.threads_leave() 
     self.main_object.value = self.main_object.value + .1 


class main(): 
    def __init__(self): 
     #GUI 
     window = gtk.Window() 
     window.set_default_size(200,200) 
     vbox = gtk.VBox(False,0) 

     self.pb = gtk.ProgressBar() 
     button = gtk.Button("Press me ") 
     button.connect("clicked",self.fun_to_call) 
     vbox.pack_end(self.pb) 
     vbox.pack_end(button) 
     button.show() 
     self.pb.show() 
     vbox.show() 
     window.add(vbox) 

     self.value = .1 
     window.show() 

    def fun_to_call(self,data=None): 
     pro = process(self) 
     pro.start() 


main() 
gtk.main() 
+1

你知道Sane绑定是否线程安全吗?如果他们不为任何长时间运行的操作执行'Py_BEGIN_ALLOW_THREADS' /'Py_END_ALLOW_THREADS'跳舞,那么他们将阻止Python代码在其他线程中执行。 –

回答

0

望着PyGTK FAQ on the subject,它似乎是你缺少的步骤; (全FAQ条目是一个有趣的阅读虽然)

...你有你的包裹与gtk.threads_enter()/ gtk.threads_leave(主循环),像这样:

gtk.threads_enter ()
gtk.main()
gtk.threads_leave()

他们也有一些建议如何使用finally以确保gtk.threads_leave()始终运行,即使该代码会抛出异常。

请注意,虽然使用这种GUI线程不一定是可移植的,但即使正确锁定,某些操作系统也可能在运行GUI操作的非主线程中出现问题。

0

标准python实现(“cpython”)的内部不是线程安全的。

所以一个锁(Global Interpreter Lock)用来确保一次只有一个python线程正在运行。这个锁被释放,例如当一个正在运行的线程执行I/O时。但是如果锁没有被释放,其他线程将无法运行。

我怀疑这是问题的根源。这取决于合理的绑定的实施。

您可以尝试使用multiprocessing模块而不是threading。多处理为长时间运行的任务启动一个完全不同的过程,所以它不受GIL的约束。但是您必须使用multiprocessing提供的工具,例如QueuePipe来交换进程之间的信息。

相关问题