如何将数据发送到正在运行的python线程? [英] How do I send data to a running python thread?

查看:271
本文介绍了如何将数据发送到正在运行的python线程?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个在我的应用程序中的单独线程中运行的类.我可以一次运行多个线程,并且这些线程是守护程序.一段时间后,其中的 some 个线程需要接收和处理消息.我该怎么做?

I have a class that is run in separate threads in my application. I can have multiple threads running at a time and the threads are daemons. After a period of time, some of these threads need to receive and process a message. How do I do this?

我的代码示例如下:

import threading
import time 

class MyThread(threading.Thread):
    def __init__(self, args=(), kwargs=None):
        threading.Thread.__init__(self, args=(), kwargs=None)
        self.daemon = True
        self.receive_messages = args[0]

    def run(self):
        print threading.currentThread().getName(), self.receive_messages

    def do_thing_with_message(self, message):
        if self.receive_messages:
            print threading.currentThread().getName(), "Received %s".format(message)

if __name__ == '__main__':
    threads = []
    for t in range(10):
        threads.append( MyThread(args=(t % 2 == 0,)))
        threads[t].start()
        time.sleep(0.1)

    for t in threads:
        t.do_thing_with_message("Print this!")

这将输出:

Thread-1 True
Thread-2 False
Thread-3 True
Thread-4 False
Thread-5 True
Thread-6 False
Thread-7 True
Thread-8 False
Thread-9 True
Thread-10 False
MainThread Received %s
MainThread Received %s
MainThread Received %s
MainThread Received %s
MainThread Received %s

但是,我希望最后五行与MainThread不相关,并且我希望它对我Print this!而不是%s,像这样:

I am expecting, however, those last five lines to not be related to the MainThread, and instead of %s, I'd expect it to me Print this!, like so:

Thread-1 True
Thread-2 False
Thread-3 True
Thread-4 False
Thread-5 True
Thread-6 False
Thread-7 True
Thread-8 False
Thread-9 True
Thread-10 False
Thread-1 Received Print this!
Thread-3 Received Print this!
Thread-5 Received Print this!
Thread-7 Received Print this!
Thread-9 Received Print this!

如何正确地向正在运行的线程发送这样的消息?

How can I properly send a message like this to the running threads?

附录:

如果我在Print this!块之后有这个块,并利用@dano的代码来解决上述问题,则它似乎没有响应这些新消息.

If I have this block after the Print this! block, and utilize @dano's code to solve the problem above, it does not seem to respond to these new messages.

for t in threads:
    t.queue.put("Print this again!")
    time.sleep(0.1)

在这种情况下,我希望输出的结尾看起来像这样

In this case, I'd expect the end of my output to look like this

Thread-1 Received Print this!
Thread-3 Received Print this!
Thread-5 Received Print this!
Thread-7 Received Print this!
Thread-9 Received Print this!
Thread-1 Received Print this again!
Thread-3 Received Print this again!
Thread-5 Received Print this again!
Thread-7 Received Print this again!
Thread-9 Received Print this again!

推荐答案

您可以使用 Queue.Queue (或Python 3中的queue.Queue):

import threading
import time 
from Queue import Queue

print_lock = threading.Lock()

class MyThread(threading.Thread):
    def __init__(self, queue, args=(), kwargs=None):
        threading.Thread.__init__(self, args=(), kwargs=None)
        self.queue = queue
        self.daemon = True
        self.receive_messages = args[0]

    def run(self):
        print threading.currentThread().getName(), self.receive_messages
        val = self.queue.get()
        self.do_thing_with_message(val)

    def do_thing_with_message(self, message):
        if self.receive_messages:
            with print_lock:
                print threading.currentThread().getName(), "Received {}".format(message)

if __name__ == '__main__':
    threads = []
    for t in range(10):
        q = Queue()
        threads.append(MyThread(q, args=(t % 2 == 0,)))
        threads[t].start()
        time.sleep(0.1)

    for t in threads:
        t.queue.put("Print this!")

    for t in threads:
        t.join()

我们将Queue实例传递给每个线程,然后使用queue.put将消息发送给Thread.我们等待消息到达run方法,该方法是Thread对象的一部分,该对象实际上在单独的执行线程中运行.收到消息后,我们将调用do_thing_with_message,它将在同一后台线程中运行.

We pass a Queue instance to each thread, and send our message to the Thread using queue.put. We wait for the message to arrive in the run method, which is the part of the Thread object that's actually running in a separate thread of execution. Once we get the message, we call do_thing_with_message, which will run in the same background thread.

我还在代码中添加了 threading.Lock ,以便打印不会混淆.

I've also added a threading.Lock to the code so the prints to stdout don't get mixed up.

如果您希望能够向该线程传递多条消息,只需使用循环:

If you want to be able to deliver multiple messages to the thread, just use a loop:

def run(self):
    print threading.currentThread().getName(), self.receive_messages
    while True:
        val = self.queue.get()
        if val is None:   # If you send `None`, the thread will exit.
            return
        self.do_thing_with_message(val)

这篇关于如何将数据发送到正在运行的python线程?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆