Closed mutonix closed 4 years ago
我当时写 stop 和 process 两把锁的主要目的是为了防止各个摄像头的图像内存被外部修改。我想的是如果在一个嵌入式平台开发商业版本的话,为了效率考虑要避免频繁分配和销毁内存,所以把对每种图像 (原始/校正/投影/鸟瞰) 放在一个全局的命名空间里面,各自使用一块固定的内存,使用 np.copyto 或者 cv::copyTo 来修改,这时候外部线程修改图像就是可能的了。
Python 里面的 queue 模块的 queue 是线程安全的,所以这个锁是多余的。主要是为了提醒迁移到 C++ 的 qt 时不要忘了这个锁。
我没有遇到你说的 qapplication 的问题,你可以贴出你的代码吗?
明白了,虽然你的代码里面摄像头内存没有放在全局空间,但考虑到未来的使用所以加了锁是吗?
QThread在使用中我遇到了一些以下疑问,以这个demo为例
import sys
from PyQt5.QtCore import QThread
import time
class Worker(QThread):
def __init__(self):
super().__init__()
def run(self):
for _ in range(10):
print(_)
time.sleep(1)
def main():
qt1 = Worker()
qt1.start()
if __name__ == '__main__':
qt1 = Worker()
qt1.start()
#main()
2.1 首先 如果直接初始化和start()的话 就会报错QEventLoop: Cannot be used without QApplication 在这之前加上app = QApplication(sys.argv)就没事 2.2 我之后试着先把这两句放到main() 再运行(就像你的代码里的一样) 好像就不会报这个错误了 所以我估计可能在全局空间会它自己会初始化一个QEventloop,但是在局部的话就不会? 2.3 另外还有个小疑问, 如果主线程先结束了,qthread的线程也会自己停掉吗(根据我实验好像是这样。。)
真的十分感谢你!!!
parent=None
这个参数,否则 qt 认为线程的持有者是某个 Qapplication 的实例。此句有误。
2.2 不清楚原因,可能是主线程被 qt 作为子线程的持有者了。
2.3 一般来说主线程结束未必导致子线程也随之结束,但是这里只有一个主进程,所以主线程结束,程序退出,自然子线程也就结束了。此句多余请问是这样写吗
class Worker(QThread):
def __init__(self, parent=None):
super(Worker, self).__init__(parent)
def run(self):
for _ in range(10):
print(_)
time.sleep(1)
但我好像还是报错, 我是不是写错了
关于子线程退出的,我以前用python的threading创建的子线程好像它主线程退出了,子线程它自己还能继续,所以这个和Qthread不太一样?
我试了一下,不调用 main 函数,直接执行确实会报你说的错误,我之前是把主线程代码放在 main 函数里面,所以碰巧没有遇到的你的问题。这个我还不清楚具体原因,需要研究一下。
如果把我那个demo用threading写的话
import sys
from threading import Thread
import time
class Worker(Thread):
def __init__(self, parent=None):
super(Worker, self).__init__(parent)
def run(self):
for _ in range(10):
print(_)
time.sleep(1)
def main():
qt1 = Worker()
qt1.start()
if __name__ == '__main__':
main()
用threading就可以得到0到9的输出,请问这是主进程等待子线程结束才自己结束的吗 好像Thread分守护线程和非守护线程
用Qthread感觉好像就是主线程运行完main()直接结束,把子线程强行停止了,QThread则直接相当于Thread的守护线程?
我猜测是因为直接在 main 函数外部写的话,主线程会先结束,这时 worker
子线程还没有结束所以 Qt 会报这个错误。在 main 函数内部写的话,主线程会等待 main 函数退出以后才结束。实际上如果在你的代码后面加上 qt1.wait()
等待子线程结束的话就不会报错。
哦,确实是这样。
我前面还有个小问题 你可能没看到,就是关于threading和Qthread比较的那个
这个应该是 Qthread 和 Python 的 Thread 的行为不一致导致的。
哦哦 好的我明白了 我的疑惑都得到了解答,真的非常非常感谢你,而且你的代码也给了我很大帮助 打扰你一下午了,实在不好意思。
抱歉我对多线程不是很熟悉 为什么需要stop_mutex 和 processing_mutex 这两把锁呢? 我看到锁里面访问的都是对象的内部属性,也不是公共的部分 以及 每个线程都初始化了自己的 stopmutex 和 processing_mutex 两把锁 ,所以线程之间也不会因为这两把锁互斥 我不是很明白
抱歉我对qt也了解不多 我自己写QThread必须要先初始化QApplication才可以正常运行,否则它会说事件循环必须要QAplication支持 我查阅了qt5文档,它说重载run函数线程就不会使用事件循环,但我还是会以下报错 QEventLoop: Cannot be used without QApplication 但我发现好像你的代码好像并不需要QApplication,请问是怎么做到的呢?
真的十分感谢!