python输入()和()打印在多线程



我使用win10和python 3.7.3 32位

我试图实现以下目标:每秒执行一次数据读出并打印,同时控制循环等待用户输入来控制设备。查看我的代码:

import device
import threading
from threading import Lock
def print_data(t_start):
while True:
data=getData() # generic example
print(f'data: {data} at time {time.time()-t_start}')
def control_func():
while True:
in_ = input(' Press ENTER to switch ON, Press x to quit')
if in_ == '':
device.on()
print('device ON')
elif in_ == 'x' or in_ == 'X':
device.off()
sys.exit()
else: continue
in_ = input(' Press ENTER to switch OFF, Press x to quit')
if in_ == '':
device.off()
print('device OFF')
elif in_ == 'x' or in_ == 'X':
device.off()
sys.exit()
else: continue
t_start = time.time()
device=device()
trd1 = threading.Thread(target=control_func())
trd2 = threading.Thread(target=print_data(t_start))

trd1.start() # starting the thread 1 
trd2.start() # starting the thread 2
trd1.join()
trd2.join()

这只给我control_func()的输入语句或print_data()的打印

与使用多处理相同。我没能让这两个函数同时运行。

替换print()
s_print_lock = Lock()
# Define a function to call print with the Lock
def s_print(*a, **b):
"""Thread safe print function"""
with s_print_lock:
print(*a, **b)

也不起作用。既然我是新手,请帮帮我。或者我应该采用不同的方法?

您在创建Thread的过程中调用了函数,您没有函数传递给Thread以使其执行,因此线程中没有发生实际的工作。修改Thread创建为:

trd1 = threading.Thread(target=control_func)  # Remove call parens
trd2 = threading.Thread(target=print_data, args=(t_start,))  # Remove call parens and pass args tuple separately

所以函数本身被传递,Thread实际上在单独的逻辑执行线程中运行它们。如前所述,您运行control_func至完成,然后运行print_data至完成,然后启动两个Thread,target=None(两个函数的返回值)不做任何事情,然后joinThread不做任何事情。

其他说明:

  1. 如果您正在使用multiprocessing,请确保使用multiprocessing.Lock,而不是threading.Lock(后者仅保证在单个进程中工作)
  2. 虽然线程情况可能不需要锁(至少在GIL保护防止问题的CPython上),如果你一次只打印一个原子的东西,对于multiprocessing,你绝对应该使用锁并将flush=True添加到所有print;如果没有flush=True,实际输出可能会无限期延迟。
  3. 你需要提供一些方法来传达循环已经完成到print_data;如前所述,control_func将返回sys.exit(),但这只退出线程,而不退出程序。除非getData因为control_func退出而抛出异常,否则print_data永远不会退出,因此主线程也不会退出。

#3的解决方案包括:

  1. 使用threading.Event();创建一个全局should_stop = threading.Event(),将print_data循环更改为while not should_stop.is_set():,并在trd1.join()返回后,让主线程调用should_stop.set()
  2. trd2设置为daemon线程,并且不必费心join它(假设它可以在trd1和主线程结束时立即死亡);可能不适用于您的场景);当所有非daemon线程退出时,它将强制死亡。

相关内容

  • 没有找到相关文章

最新更新