python获取线程id_python – 正确使用QThread.currentThreadId()

我认为确定当前运行函数的QThread的ID是QThread.currentThreadId().但是我发现这没有给出预期的结果(在PyQt5中使用

python 3;但是我没有理由相信它与pyqt4 / py 2不同,因此通用标签).线程ID以我无法解释的方式变化,表明我实际上无法使用它,QThread实例id可预测地变化,表明我应该使用它来识别当前正在运行的线程.为了测试,我创建了这个:

from PyQt5 import QtCore, QtWidgets

from PyQt5.QtCore import pyqtSignal

import time

import sys

def logthread(caller):

print('%-25s: %s, %s' % (caller, QtCore.QThread.currentThread(), QtCore.QThread.currentThreadId()))

class Worker(QtCore.QObject):

done = pyqtSignal()

def __init__(self, parent=None):

logthread('worker.__init__')

super().__init__(parent)

def run(self, m=10):

logthread('worker.run')

for x in range(m):

y = x + 2

time.sleep(0.001)

logthread('worker.run finished')

self.done.emit()

class MainWindow(QtWidgets.QWidget):

def __init__(self, parent=None):

logthread('mainwin.__init__')

super().__init__(parent)

self.worker = Worker()

self.workerThread = None

self.btn = QtWidgets.QPushButton('Start worker in thread')

self.btn2 = QtWidgets.QPushButton('Run worker here')

layout = QtWidgets.QVBoxLayout(self)

layout.addWidget(self.btn)

layout.addWidget(self.btn2)

self.run()

def run(self):

logthread('mainwin.run')

self.workerThread = QtCore.QThread()

self.worker.moveToThread(self.workerThread)

self.worker.done.connect(self.workerDone)

self.btn.clicked.connect(self.worker.run)

self.btn2.clicked.connect(self.runWorkerHere)

self.workerThread.start()

self.show()

def workerDone(self):

logthread('mainwin.workerDone')

def runWorkerHere(self):

logthread('mainwin.runWorkerHere')

self.worker.run()

if __name__ == '__main__':

app = QtWidgets.QApplication([])

logthread('main')

window = MainWindow()

sys.exit(app.exec_())

当你运行它时,前4行打印出现在进入事件循环之前,并显示QThread.currentThread()Python id在几个位置是不同的,但QThread.currentThreadId()是相同的:

main : ,

mainwin.__init__ : ,

worker.__init__ : ,

mainwin.run : ,

我希望所有QThread Python id都相同,但是好的可能是QThread的几个实例包装了相同的C线程指针.

现在单击“在此处运行worker”按钮:这只是直接从GUI线程调用worker.run方法,因此该方法应该指示它正在该线程中运行.这打印出这四行:

mainwin.runWorkerHere : ,

worker.run : ,

worker.run finished : ,

mainwin.workerDone : ,

实际上这次QThread实例ID在所有行上都是相同的,很高兴看到.但是第3行中的线程ID不同,由于worker.run中的信号而被插槽打印的行,但信号是在同一个线程中生成的!此外,这意味着相同的QThread对象可以具有多个底层线程ID.

现在单击“Start Worker”.这会调用worker.run,但是在worker的线程中.印刷的3行是:

worker.run : ,

worker.run finished : ,

mainwin.workerDone : ,

在worker.run(前两行)内的QThread实例ID与插槽中的不同,这是有道理的.同样,线程id(sip.voidptr)以对我没有意义的方式变化:我希望第2行显示线程ID 0x01A4ABC0,与第一行相同,而不是与第3行(槽)相同.

有趣的是,如果用QtWidgets.QApplication.instance().thread()替换logthread格式的线程id输出,你会发现QThread实例id总是与应用程序QThread实例id相同,除非运行worker.run`在单独的线程中.甚至在输入应用程序事件循环之前(换句话说,应用程序线程id仅在事件循环开始后才变为常量).

如果我正在测试这个权限,上面指出QThread实例ID在QApplication事件循环开始后具有一致且可预测的值,但是线程id(currentThreadId())没有.因此,每当我想测试运行的函数的线程位置时,我应该使用QThread.currentThread()并可能与app.thread()进行比较,但我应该避免使用currentThreadId().有人看到我测试这个和结论的方式有任何问题吗?如果没有问题,给定currentThreadId()的文档,这有什么意义呢?如果我弄错了,我做错了什么?

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值