Python: 如何等待一个函数在不同的线程中被调用?
Python: How to wait until a function has been called in a different thread?
我在线程 A 中有一个函数需要等到线程 B 中的函数被调用。
线程B中的函数是周期性调用的,所以只需要等到下次调用即可。这让我可以与它同步。
我该怎么做?
(抱歉,如果这是微不足道的。)
没有多线程问题是微不足道的,这可能是计算机科学的一个原则。
有多种方法可以做到这一点,但最简单的方法之一是使用 threading.Event 对象。事件是所谓的同步原语中最简单的。有关更多想法,请参阅有关线程模块的手册部分。这是一个工作示例:
#! python3.8
import threading
import time
t0 = time.time()
def elapsed_time():
return time.time() - t0
class StopMe:
def __init__(self):
self.running = True
def main():
ev1 = threading.Event()
stop = StopMe()
th1 = threading.Thread(target=thread1, args=(ev1, stop))
th1.start()
for _ in range(10):
ev1.wait()
print("The function was just called", elapsed_time())
ev1.clear()
stop.running = False
th1.join()
print("Exit", elapsed_time())
def thread1(event, stop):
def a_function():
event.set()
print("I am the function", elapsed_time())
while stop.running:
time.sleep(1.0)
a_function()
main()
输出:
I am the function 1.0116908550262451
The function was just called 1.0116908550262451
I am the function 2.0219264030456543
The function was just called 2.0219264030456543
I am the function 3.0322916507720947
The function was just called 3.0322916507720947
I am the function 4.033170938491821
The function was just called 4.033170938491821
I am the function 5.043376445770264
The function was just called 5.043376445770264
I am the function 6.043909788131714
The function was just called 6.043909788131714
I am the function 7.054021596908569
The function was just called 7.054021596908569
I am the function 8.06399941444397
The function was just called 8.06399941444397
I am the function 9.064924716949463
The function was just called 9.064924716949463
I am the function 10.066757678985596
The function was just called 10.066757678985596
I am the function 11.076870918273926
Exit 11.076870918273926
这里有几点需要注意:
将同步原语放入代码后,您需要考虑如何优雅地终止线程,以及如何终止整个应用程序。在此示例中,线程通过小 "StopMe" 对象和 Event 对象进行通信。请注意,主线程可能必须等待一秒钟,直到辅助线程完成其睡眠功能。如果 thread1 在主线程调用 join 函数之前开始其时间延迟,则会发生这种情况。这在我的测试中没有发生 运行 但它可能会发生,这取决于如何将 CPU 时间片分配给不同的线程。如果您不能接受,您必须编写更多代码来解决它。
另请注意,函数调用 ev1.wait() 将阻塞主线程,直到从辅助线程设置事件。在不是您想要的 GUI 应用程序中。
我 运行 使用 Python3.8 但该程序不使用任何版本特定的功能,因此它应该与 Python 的任何较新版本相同.
我在线程 A 中有一个函数需要等到线程 B 中的函数被调用。
线程B中的函数是周期性调用的,所以只需要等到下次调用即可。这让我可以与它同步。
我该怎么做?
(抱歉,如果这是微不足道的。)
没有多线程问题是微不足道的,这可能是计算机科学的一个原则。
有多种方法可以做到这一点,但最简单的方法之一是使用 threading.Event 对象。事件是所谓的同步原语中最简单的。有关更多想法,请参阅有关线程模块的手册部分。这是一个工作示例:
#! python3.8
import threading
import time
t0 = time.time()
def elapsed_time():
return time.time() - t0
class StopMe:
def __init__(self):
self.running = True
def main():
ev1 = threading.Event()
stop = StopMe()
th1 = threading.Thread(target=thread1, args=(ev1, stop))
th1.start()
for _ in range(10):
ev1.wait()
print("The function was just called", elapsed_time())
ev1.clear()
stop.running = False
th1.join()
print("Exit", elapsed_time())
def thread1(event, stop):
def a_function():
event.set()
print("I am the function", elapsed_time())
while stop.running:
time.sleep(1.0)
a_function()
main()
输出:
I am the function 1.0116908550262451
The function was just called 1.0116908550262451
I am the function 2.0219264030456543
The function was just called 2.0219264030456543
I am the function 3.0322916507720947
The function was just called 3.0322916507720947
I am the function 4.033170938491821
The function was just called 4.033170938491821
I am the function 5.043376445770264
The function was just called 5.043376445770264
I am the function 6.043909788131714
The function was just called 6.043909788131714
I am the function 7.054021596908569
The function was just called 7.054021596908569
I am the function 8.06399941444397
The function was just called 8.06399941444397
I am the function 9.064924716949463
The function was just called 9.064924716949463
I am the function 10.066757678985596
The function was just called 10.066757678985596
I am the function 11.076870918273926
Exit 11.076870918273926
这里有几点需要注意:
将同步原语放入代码后,您需要考虑如何优雅地终止线程,以及如何终止整个应用程序。在此示例中,线程通过小 "StopMe" 对象和 Event 对象进行通信。请注意,主线程可能必须等待一秒钟,直到辅助线程完成其睡眠功能。如果 thread1 在主线程调用 join 函数之前开始其时间延迟,则会发生这种情况。这在我的测试中没有发生 运行 但它可能会发生,这取决于如何将 CPU 时间片分配给不同的线程。如果您不能接受,您必须编写更多代码来解决它。
另请注意,函数调用 ev1.wait() 将阻塞主线程,直到从辅助线程设置事件。在不是您想要的 GUI 应用程序中。
我 运行 使用 Python3.8 但该程序不使用任何版本特定的功能,因此它应该与 Python 的任何较新版本相同.