2012-01-27 4 views
2

Для простой чат-программы я использую c lib, который обернут через boost :: python.Блокировка блоков QThread GUI

Простой графический интерфейс написан с использованием PyQT. Прием сообщений осуществляется с помощью блокирующего вызова до . Для того, чтобы графический интерфейс обновлялся независимо, часть связи находится в QThread.

В то время как я предполагаю графический интерфейс пользователя и связь, чтобы быть независимым, 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_() 

ответ

6

Это может быть вызвано пресловутого глобального интерпретатора Блокировка (ГИЛ). Python не позволяет двум потокам одновременно выполнять код Python. В вашей функции C вы должны явно освободить и повторно приобрести GIL, если вы хотите, чтобы ваш графический интерфейс работал параллельно.

Это объясняется в документации API Python C: Thread State and the Global Interpreter Lock.

Она сводится к тому, используя следующие макросы в расширении C:

Py_BEGIN_ALLOW_THREADS 

// Your expensive computation goes here. 

Py_END_ALLOW_THREADS 
+0

Не достаточно позорный;) Работает как шарм прямо сейчас! – joekr

Смежные вопросы