为了账号安全,请及时绑定邮箱和手机立即绑定

Python 从后台线程在主线程上运行函数

Python 从后台线程在主线程上运行函数

达令说 2023-10-06 19:23:04
这样创建了一个后台线程 def listenReply(self):        while self.SOCK_LISTENING:            fromNodeRED = self.nodeRED_sock.recv(1024).decode()            if fromNodeRED=="closeDoor":                self.door_closed() ...    self.listenThread = Thread(target=self.listenReply, daemon=True)    self.SOCK_LISTENING = True    self.listenThread.start()但是 self.door_close() 有一些 UI 的东西,所以这不好。如何在主线程中调用 self.door_close ?
查看完整描述

3 回答

?
呼如林

TA贡献1798条经验 获得超3个赞

需要记住的一件事是,每个线程都是单个代码流的顺序执行,从线程启动的函数开始。简单地在现有线程上运行某些内容没有多大意义,因为该线程已经在执行某些内容,并且这样做会破坏它的当前流程。


然而,线程之间的通信非常容易,并且可以实现线程的代码,使其仅从其他线程接收函数/事件来告诉它要做什么。这通常称为事件循环。


例如你的主线程可能看起来像这样


from queue import Queue


tasks = Queue()


def event_loop():

   while True:

       next_task = tasks.get()

       print('Executing function {} on main thread'.format(next_task))

       next_task()

在其他线程中,您可以通过简单地将函数添加到队列中来要求主线程运行该函数tasks:


 def listenReply(self):

    while self.SOCK_LISTENING:

        fromNodeRED = self.nodeRED_sock.recv(1024).decode()

        if fromNodeRED=="closeDoor":

            tasks.put(door_closed)


查看完整回答
反对 回复 2023-10-06
?
狐的传说

TA贡献1804条经验 获得超3个赞

我自己使用 PyQt 的信号和插槽解决了这个问题。


class App(QWidget):


    socketSignal = QtCore.pyqtSignal(object) #must be defined in class level


    # BG THREAD

    def listenReply(self):

        while self.SOCK_LISTENING:

            fromNodeRED = self.nodeRED_sock.recv(1024).decode()

            print(fromNodeRED)

            self.socketSignal.emit(fromNodeRED)

....主线程 init 中的某处:


    self.socketSignal.connect(self.executeOnMain)

    self.listenThread = Thread(target=self.listenReply, daemon=True)

    self.SOCK_LISTENING = True

    self.listenThread.start()

       

....


def executeOnMain(self, data):

     if data=="closeDoor":

            self.door_closed() # a method that changes the UI

对我来说效果很好。


查看完整回答
反对 回复 2023-10-06
?
有只小跳蛙

TA贡献1824条经验 获得超8个赞

threading.Event()每当您收到来自 的“closeDoor”消息时,您都可以使用和设置它recv。


例如:


g_should_close_door = threading.Event()


def listenReply(self):

    while self.SOCK_LISTENING:

        fromNodeRED = self.nodeRED_sock.recv(1024).decode()

        if fromNodeRED=="closeDoor":

            g_should_close_door.set()


    ...


    self.listenThread = Thread(target=self.listenReply, daemon=True)

    self.SOCK_LISTENING = True

    self.listenThread.start()


    if g_should_close_door.is_set():

        door_closed() 

        g_should_close_door.clear() 


查看完整回答
反对 回复 2023-10-06
  • 3 回答
  • 0 关注
  • 86 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信