主线程和QThread相互阻塞

2024-10-01 13:36:44 发布

您现在位置:Python中文网/ 问答频道 /正文

我已经在stackoverflow上搜索了很长一段时间,但我没有找到问题的答案。我在这里尝试了许多建议,但都没有成功

我的问题是,我正在创建一个套接字,它将在一个单独的线程上运行,并在主线程执行其他任务时发回所有接收到的数据。下面是我尝试运行的最小main()

#! /usr/bin/env python

from PyQt5 import QtCore, QtGui, QtWidgets
from threadSockRecon import threadSocket
import time

def show_response(data):
    print(str(data))

def main():

    # This section runs the myreceive function loop and receives fine
    # (does not send back to main and main does not loop)
    mySock = threadSocket()
    mySock.connect('127.0.0.1', 8011)
    sockThread = QtCore.QThread()
    mySock.signalStart.emit()
    mySock.moveToThread(sockThread)
    sockThread.start()
    mySock.signalRcvd.connect(show_response)



    # Below will run main thread but not the recieve thread
    # (can send without problems)
    '''
    mySock = threadSocket()
    mySock.connect('127.0.0.1', 8011)
    sockThread = QtCore.QThread()
    mySock.moveToThread(sockThread)
    sockThread.start()
    mySock.signalRcvd.connect(show_response)
    mySock.signalStart.emit()
    '''

    while True:
        print("Spinning ...")
        sMessage = ' getstatus '
        mySock.signalSend.emit(sMessage)
        time.sleep(2)

if (__name__ == "__main__"):
    main()

如您所见,这将调用名为“threadSocket”的套接字类。下面是这个班

# threaded socket
#!/usr/bin/env python

from PyQt5 import QtCore
import sys, socket
import time

BUFFER_SIZE = 2048

class threadSocket(QtCore.QObject):
    signalStart = QtCore.pyqtSignal()
    signalSend = QtCore.pyqtSignal(str) 
    signalRcvd = QtCore.pyqtSignal(str)

    def __init__(self, parent=None):
        super(self.__class__, self).__init__(parent)
        self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.signalStart.connect(self.myreceive)
        self.signalSend.connect(self.mysend)


    def connect(self, host, port):
        try:
            self.sock.connect((host, port))
            print("connected")
        except socket.error as e:
            print("\nConnecting error occurred: " + str(e)  + "\n")
        else:
            pass

    def mysend(self, msg):
        totalsent = 0
        try:
            while totalsent < len(msg):
                sent = self.sock.send(msg[totalsent:].encode('UTF-8'))
                if sent == 0:
                    raise RuntimeError("socket connection broken")
                totalsent = totalsent + sent
        except socket.error as e:
            print("\nMysend error occurred: " + str(e)  + "\n")
        else:
            pass

    @QtCore.pyqtSlot()
    def myreceive(self):
        print("Receiving...")
        chunks = []
        while True:
            try:
                chunk = self.sock.recv(BUFFER_SIZE)
                print("chunk: " + str(chunk))
                if chunk == b'':
                    raise RuntimeError("socket connection broken")
                chunks.append(chunk)
                if ((len(chunks) >= BUFFER_SIZE) or (len(chunks) > 0)):
                    self.signalRcvd.emit(str(b''.join(chunks)))
                    chunks = []
                time.sleep(0.5)
            except RuntimeError as e:
                # put code in here to attempt reconnect
                print("ERROR: Connection Lost: " + str(e) + "\n")
                self.signalRcvd.emit("ERROR")
            except socket.error as e:
                print("\nMyreceive encountered an error: " + str(e) + "\n")
                self.signalRcvd.emit("ERROR")
            else:
                pass

    def close(self):
        print("socket closing")
        self.sock.close()

正如我在main()中的评论所示,我无法让它们同时运行。我做错什么了?事先谢谢你的帮助(使用Python 3.5.2和pyqt5)


Tags: importselfmaindefconnecterrorsocketchunks