如何将数据发送到正在运行的python线程? [英] How do I send data to a running python thread?
问题描述
我有一个在我的应用程序中的单独线程中运行的类.我可以一次运行多个线程,并且这些线程是守护程序.一段时间后,其中的 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屋!