Блокировка QThread блокирует графический интерфейс - PullRequest
2 голосов
/ 27 января 2012

Для простой программы чата я использую ac lib, которая обёрнута через boost :: python.

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

Хотя я бы предположил, что графический интерфейс и коммуникация независимы, графический интерфейс крайне не отвечает и, кажется, обновляется только при поступлении сообщений.1005 *

#!/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_()

1 Ответ

6 голосов
/ 27 января 2012

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

Это объясняется в документации по API Python C: Состояние потока иГлобальная блокировка интерпретатора .

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

Py_BEGIN_ALLOW_THREADS

// Your expensive computation goes here.

Py_END_ALLOW_THREADS
...