Python 从QThread.run调用cython函数时pyqt gui被锁定
在PyQt4中,我希望执行无锁gui的代码。 我使用QThread和emit信号进行gui更新。 但若我在QThread.run中调用cython函数,gui将被锁定Python 从QThread.run调用cython函数时pyqt gui被锁定,python,user-interface,pyqt,cython,qthread,Python,User Interface,Pyqt,Cython,Qthread,在PyQt4中,我希望执行无锁gui的代码。 我使用QThread和emit信号进行gui更新。 但若我在QThread.run中调用cython函数,gui将被锁定 class Runner(QtCore.QThread): iter = QtCore.pyqtSignal(int) def __init__(self): QtCore.QThread.__init__(self) def do_something(self): be
class Runner(QtCore.QThread):
iter = QtCore.pyqtSignal(int)
def __init__(self):
QtCore.QThread.__init__(self)
def do_something(self):
beg = time.time()
s = 0.0
while time.time() - beg < 1:
s += math.sqrt(1000)
def run(self):
for it in xrange(10):
# no lock gui
#self.do_something()
# lock gui
cython_unit.do_something()
self.iter.emit(it + 1)
类运行程序(QtCore.QThread):
iter=QtCore.pyqtSignal(int)
定义初始化(自):
QtCore.QThread.\uuuu init\uuuuu(self)
def do_某事(自我):
beg=时间。时间()
s=0.0
而time.time()-beg<1:
s+=数学sqrt(1000)
def运行(自):
对于X范围(10)中的it:
#无锁gui
#self.做点什么
#锁gui
辛顿单位,做点什么
自.iter.emit(it+1)
cython_unit.pyx:
import math
import time
def do_something():
beg = time.time()
s = 0.0
while time.time() - beg < 1:
s += math.sqrt(1000)
导入数学
导入时间
定义做某事():
beg=时间。时间()
s=0.0
而time.time()-beg<1:
s+=数学sqrt(1000)
测试项目在这里:由于GIL(全局解释器锁),一次只能执行一个Python实例。Python如何选择在线程之间共享时间在一定程度上取决于Python的版本,但实际上取决于执行了多少Python字节码(请参阅)
我猜,由于Cython实际上不运行任何Python字节码,因此它不会释放GIL,因此您的显示将被锁定。您可以使用nogil的手动释放GIL
。在最坏的情况下,我认为添加:
with nogil:
pass
到你的循环将工作。但是,您的一些代码完全可以在没有GIL的情况下完成(即不使用python特性):
libc.math cimport sqrt中的不要使用Python数学模块
导入时间
定义做某事():
beg=时间。时间()
cdef double s=0#类型为double,而不是python对象
而time.time()-beg<1:
诺吉尔:
s+=sqrt(1000)#现在使用C-sqrt,而不是python
如果需要,还可以使用libc时间函数,并使用nogil块将几乎整个函数包装在中,在这种情况下,它不应该阻止GUI
from libc.math cimport sqrt # don't use Python math module
import time
def do_something():
beg = time.time()
cdef double s = 0 # typed as a double, not a python object
while time.time() - beg < 1:
with nogil:
s += sqrt(1000) # now using C sqrt, not the python one