Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/user-interface/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 从QThread.run调用cython函数时pyqt gui被锁定_Python_User Interface_Pyqt_Cython_Qthread - Fatal编程技术网

Python 从QThread.run调用cython函数时pyqt 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

在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):
        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