joe*_*ekr 2 python multithreading boost pyqt qthread
对于一个简单的聊天程序,我使用通过boost :: python包装的ac lib.
使用PyQT编写一个简单的GUI.通过对所述lib的阻塞调用来完成接收消息.为了使GUI独立刷新,通信部分处于QThread中.
虽然我认为GUI和通信是独立的,但GUI非常无响应,似乎只在消息进入时才更新.
#!/usr/bin/env python
import sys
from PyQt4.QtCore import *
from PyQt4.QtGui import *
import pynetcom2
import time
class NetCom(QThread):
def __init__(self):
QThread.__init__(self)
self.client = pynetcom2.Client()
self.client.init('127.0.0.1', 4028)
self.client.provide('myChat', 1)
self.client.subscribe('myChat', 100)
def run(self):
while (1):
print "Waiting for message..."
text = self.client.recvStr('myChat', True)
return
class Netchat(QMainWindow):
def __init__(self, argv):
if (len(argv) != 2):
print "Usage: %s <nickname>" %(argv[0])
sys.exit(1)
self.nickname = argv[1]
print "Logging in with nickname '%s'" %(self.nickname)
super(Netchat, self).__init__()
self.setupUI()
rect = QApplication.desktop().availableGeometry()
self.resize(int(rect.width() * 0.3), int(rect.height() * 0.6))
self.show()
self.com = NetCom()
self.com.start()
def setupUI(self):
centralWidget = QWidget()
self.setCentralWidget(centralWidget)
self.testList = QListWidget()
mainLayout = QHBoxLayout()
mainLayout.addWidget(self.testList)
centralWidget.setLayout(mainLayout)
if __name__ == "__main__":
app = QApplication(sys.argv)
netchat = Netchat(sys.argv)
app.exec_()
Run Code Online (Sandbox Code Playgroud)
这可能是由臭名昭着的全球口译员锁(GIL)引起的.Python不允许两个线程同时执行Python代码.在C函数中,如果希望GUI代码并行运行,则必须显式释放并重新获取GIL.
Python C API文档中解释了这一点:线程状态和全局解释器锁.
归结为在C扩展中使用以下宏:
Py_BEGIN_ALLOW_THREADS
// Your expensive computation goes here.
Py_END_ALLOW_THREADS
Run Code Online (Sandbox Code Playgroud)