让一个单独的线程将请求推送到python中的主线程

2024-05-14 14:33:41 发布

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

我希望有一个线程在后台运行,但在再次运行之前,会将请求推送到主线程进行输入。理想情况下,如果在运行线程时未满足某个条件,则应在第二个线程上恢复之前请求输入

from threading import Thread

def myfun(numofcycles = None):
    if numofcycles is None:
       myrange = range(0,input('Enter number of cycles: '))
    else:
       myrange = range(0,numofcycles)

    for x in myrange:
         print(x)
t = Thread(target=myfun, args = (numofcycles)) # Start the thread
t.start()

Tags: fromimportnone情况range条件线程thread
1条回答
网友
1楼 · 发布于 2024-05-14 14:33:41

线程化

queue.Queue对象非常适合在线程之间进行同步和在线程之间传递数据。下面我让线程1等待从线程2发送的命令执行。您可以通过队列在线程之间传递任何类型的数据。如您所见,我通过队列将函数及其参数传递给线程1

>>> import queue
>>> import threading as th
>>> import time
>>> 
>>> def thread_func_1(q, n_cycles=2):
...     for _ in range(n_cycles):
...         print("waiting for request from thread 2")
...         try:
...             task, args, kwargs = q.get(timeout=4)
...             print("got request. executing...")
...             task(*args, **kwargs)
...         except queue.Empty:
...             print("timed out waiting for a request")
...             
>>> def thread_func_2(q, n_cycles=2):
...     for _ in range(n_cycles):
...         time.sleep(1)
...         print("sending request to thread 1")
...         q.put((print, ('hello world',), {},))
...         
>>> q    = queue.Queue()
>>>
>>> th_1 = th.Thread(target=thread_func_1, args=(q, 2,))
>>> th_2 = th.Thread(target=thread_func_2, args=(q, 2,))
>>> 
>>> th_1.start(); th_2.start()

waiting for request from thread 2
got request. executing...
hello world
waiting for request from thread 2
got request. executing...
hello world
sending request to thread 1
sending request to thread 1

有趣的是,在元组中的最后一个项后面放一个逗号会产生不同。这样做修复了thread-2中的文本-它是h e l l o w o r l d之前的

现在让其他线程能够请求主线程代表它们执行任务,这与此类似,因为主线程只是另一个线程

主线程任务处理程序

你可以在执行其他任务的主线程中运行一个任务处理程序循环,这样应用程序就不会停滞不前。。然后检查公共queue.Queue请求。当它看到一个时,它可以抓取它并执行它,然后将结果发送回请求者

您可能需要多个队列来支持将请求结果发送回其发件人。为了实现这一点,我们让其他线程保留它们自己的Queue,并将它们传递给请求中的主线程,以便主线程可以将结果发送回请求

>>> def main_loop(q, n_cycles=2):
...     for _ in range(n_cycles):
...         try:
...             #task, args, kwargs, client_queue = q.get(block=False)
...             task, args, kwargs, client_queue = q.get(timeout=4)
...
...             print(f"Executing {task.__name__}() for other thread...")
...
...             result = task(*args, **kwargs)
...             client_queue.put(result)
...
...         except queue.Empty:
...             print("Queue was empty, nothing to do...")
...
...             time.sleep(0) # So app doesn't bog down, relinquish control
...                           # when idle to let other threads have more time.

这提供了在主线程上运行的任务队列循环的大致概念。您不想阻止读取队列(我只是有一个超时的例子)

另外一个好提示是,当主线程空闲时,总是在循环中放置一个time.sleep(0)。这使得应用程序保持响应,并给其他线程更多的时间来完成他们的工作。如果没有睡眠,应用程序可能会变得迟钝,因为主线程在大部分时间都在自私自利地浪费处理器周期

<强>需考虑的事项-多重处理<强/> /P>

如果应用程序确实需要通过运行并发线程来充分利用CPU的处理能力,Python的threading模块不支持这一点。一次只能有一个线程主动运行Python代码(每个解释器)

为了让工人真正并发地运行,multiprocessing模块是一种可行的方法。它支持与multithreading模块类似的API,但使用进程而不是线程

相关问题 更多 >

    热门问题