Python 线程不适用于pygtk,始终挂起

Python 线程不适用于pygtk,始终挂起,python,multithreading,user-interface,pygtk,Python,Multithreading,User Interface,Pygtk,下面是我的问题的一个小实现。当我点击“按下”按钮时,它会挂起,有时不会。怎样才能克服这个悬念? 这是我的密码 安装Sane“sudo apt get install python imaging Sane” 看着这些,你似乎错过了一步;(整个FAQ条目是一本有趣的读物) …您必须使用gtk.threads\u enter()/gtk.threads\u leave()来包装主循环,如下所示: gtk.threads_enter() gtk.main() gtk.threads_leave() 他

下面是我的问题的一个小实现。当我点击“按下”按钮时,它会挂起,有时不会。怎样才能克服这个悬念? 这是我的密码

安装Sane“sudo apt get install python imaging Sane”

看着这些,你似乎错过了一步;(整个FAQ条目是一本有趣的读物)

…您必须使用gtk.threads\u enter()/gtk.threads\u leave()来包装主循环,如下所示:

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

他们还建议如何使用
finally
来确保
gtk.threads_leave()
始终运行,即使代码引发异常


请注意,尽管使用这种GUI线程不一定是可移植的,但某些操作系统可能会遇到非主线程运行GUI操作的问题,即使锁定正确

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

因此,使用锁(the)来确保一次只运行一个python线程。例如,当一个正在运行的线程执行I/O操作时,会释放此锁。但是如果不释放该锁,其他线程将没有机会运行

我怀疑这是问题的根源。这取决于sane绑定的实现


您可以尝试使用模块而不是
线程化
。多处理为长时间运行的任务启动一个完全不同的进程,因此它不受GIL的约束。但是您必须使用
多处理
提供的工具,如
队列
管道
在进程之间交换信息。

您知道Sane绑定是否是线程安全的吗?如果他们不为任何长时间运行的操作执行
Py\u BEGIN\u ALLOW\u THREADS
/
Py\u END\u ALLOW\u THREADS
舞蹈,那么他们将阻止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()