嗨,我有一个程序,读取多个传感器,记录和图表的数据。并可根据传感器值启动程序。我的问题是,程序需要等待物理硬件来执行它们的操作。假设我有两个模拟传感器。如果s1的模拟值低于X,则启动P1,需要30秒。如果s2的模拟值低于Y程序,则启动P2,也需要30秒。因此,通过使用睡眠(30),我阻塞了程序的其余部分。因此,我的治疗方法是使用睡眠(1)并记录数据。如果P1仍在运行,而s2低于Y,那么问题就产生了--在这种情况下,我找不到好的解决方案。会不会像异步多处理一样工作。所以在新线程或类似的线程中运行这两个进程。如果是的话,我该怎么做呢?
发布于 2022-02-01 15:31:32
下面是问题的Minimal Reproducible Example:
import logging
import time
_values_for_sensor_a = iter([0, 0, 456, 0, 0])
_values_for_sensor_b = iter([0, 0, 0, 0, 0])
def read_sensor_a() -> int:
return next(_values_for_sensor_a) # example !
def read_sensor_b() -> int:
return next(_values_for_sensor_b) # example !
def procedure_p1() -> None:
logging.info("beginning procedure P1")
time.sleep(5) # shorter than your 30 seconds
logging.info("ending procedure P1")
def procedure_p2() -> None:
logging.info("beginning procedure P2")
time.sleep(5) # shorter than your 30 seconds
logging.info("ending procedure P2")
if __name__ == "__main__":
# setup
logger = logging.getLogger(None)
log_handler = logging.StreamHandler()
log_handler.setFormatter(logging.Formatter("%(asctime)s %(message)s"))
logger.addHandler(log_handler)
logger.setLevel(logging.DEBUG)
# operating ...
while True:
measure_a = read_sensor_a()
logging.info(f"{measure_a=:.0f}")
measure_b = read_sensor_b()
logging.info(f"{measure_b=:.0f}")
if measure_a > 100:
# quick, initiate procedure P1 !
procedure_p1()
elif measure_b > 100:
procedure_p2()
logger.info("short pause")
time.sleep(0.1)
2022-02-01 16:19:00,932 measure_a=0
2022-02-01 16:19:00,932 measure_b=0
2022-02-01 16:19:00,932 short pause
2022-02-01 16:19:01,933 measure_a=0
2022-02-01 16:19:01,933 measure_b=0
2022-02-01 16:19:01,933 short pause
2022-02-01 16:19:02,934 measure_a=456
2022-02-01 16:19:02,934 measure_b=0
2022-02-01 16:19:02,934 /!\ beginning procedure P1
2022-02-01 16:19:07,936 /!\ ending procedure P1
2022-02-01 16:19:07,936 short pause
2022-02-01 16:19:08,938 measure_a=0
2022-02-01 16:19:08,938 measure_b=0
2022-02-01 16:19:08,938 short pause
2022-02-01 16:19:09,939 measure_a=0
2022-02-01 16:19:09,939 measure_b=0
2022-02-01 16:19:09,939 short pause
实际上,传感器读取中有5秒的暂停,因为运行您的Python代码的线程很忙(在本例中它正忙着睡觉)。
解决方案是有多个线程,这样读取值的线程就不会忙着做其他事情了。
import itertools
import logging
import time
import threading
_values_for_sensor_a = iter(itertools.chain([0, 0, 456], itertools.repeat(0))) # 0, 0, 456, then always 0
_values_for_sensor_b = iter(itertools.chain([0, 0, 0, 0, 789], itertools.repeat(0))) # 0, 0, 0, 0, 789 then always 0
def read_sensor_a() -> int:
return next(_values_for_sensor_a) # example !
def read_sensor_b() -> int:
return next(_values_for_sensor_b) # example !
def procedure_p1() -> None:
logging.info("/!\ beginning procedure P1")
time.sleep(5) # shorter than your 30 seconds
logging.info("/!\ ending procedure P1")
def procedure_p2() -> None:
logging.info("/!\ beginning procedure P2")
time.sleep(5) # shorter than your 30 seconds
logging.info("/!\ ending procedure P2")
if __name__ == "__main__":
# setup
logger = logging.getLogger(None)
log_handler = logging.StreamHandler()
log_handler.setFormatter(logging.Formatter("%(asctime)s %(threadName)s %(message)s")) # <-- added `threadName`
logger.addHandler(log_handler)
logger.setLevel(logging.DEBUG)
threads_running = []
# operating ...
while True:
measure_a = read_sensor_a()
logging.info(f"{measure_a=:.0f}")
measure_b = read_sensor_b()
logging.info(f"{measure_b=:.0f}")
if measure_a > 100:
thread = threading.Thread(target=procedure_p1, args=[])
thread.start()
threads_running.append(thread)
elif measure_b > 100:
thread = threading.Thread(target=procedure_p2, args=[])
thread.start()
threads_running.append(thread)
# check if one procedure has finished
for thread in threads_running:
thread.join(timeout=0) # non-blocking because timeout=0
if thread.is_alive():
# the join has timeout, so the thread is still running
pass
else:
threads_running.remove(thread)
logging.info(f"removing thread {thread.name}")
logger.info("short pause\n")
time.sleep(1)
2022-02-01 16:30:06,145 MainThread measure_a=0
2022-02-01 16:30:06,145 MainThread measure_b=0
2022-02-01 16:30:06,145 MainThread short pause
2022-02-01 16:30:07,145 MainThread measure_a=0
2022-02-01 16:30:07,145 MainThread measure_b=0
2022-02-01 16:30:07,146 MainThread short pause
2022-02-01 16:30:08,147 MainThread measure_a=456
2022-02-01 16:30:08,147 MainThread measure_b=0
2022-02-01 16:30:08,147 Thread-1 /!\ beginning procedure P1
2022-02-01 16:30:08,147 MainThread short pause
2022-02-01 16:30:09,148 MainThread measure_a=0
2022-02-01 16:30:09,148 MainThread measure_b=0
2022-02-01 16:30:09,148 MainThread short pause
2022-02-01 16:30:10,149 MainThread measure_a=0
2022-02-01 16:30:10,150 MainThread measure_b=456
2022-02-01 16:30:10,150 Thread-2 /!\ beginning procedure P2
2022-02-01 16:30:10,150 MainThread short pause
2022-02-01 16:30:11,151 MainThread measure_a=0
2022-02-01 16:30:11,151 MainThread measure_b=0
2022-02-01 16:30:11,151 MainThread short pause
2022-02-01 16:30:12,152 MainThread measure_a=0
2022-02-01 16:30:12,152 MainThread measure_b=0
2022-02-01 16:30:12,152 MainThread short pause
2022-02-01 16:30:13,152 Thread-1 /!\ ending procedure P1
2022-02-01 16:30:13,153 MainThread measure_a=0
2022-02-01 16:30:13,154 MainThread measure_b=0
2022-02-01 16:30:13,154 MainThread removing thread Thread-1
2022-02-01 16:30:13,154 MainThread short pause
2022-02-01 16:30:14,155 MainThread measure_a=0
2022-02-01 16:30:14,155 MainThread measure_b=0
2022-02-01 16:30:14,155 MainThread short pause
2022-02-01 16:30:15,155 Thread-2 /!\ ending procedure P2
2022-02-01 16:30:15,156 MainThread measure_a=0
2022-02-01 16:30:15,156 MainThread measure_b=0
2022-02-01 16:30:15,156 MainThread removing thread Thread-2
2022-02-01 16:30:15,156 MainThread short pause
2022-02-01 16:30:16,157 MainThread measure_a=0
2022-02-01 16:30:16,158 MainThread measure_b=0
2022-02-01 16:30:16,158 MainThread short pause
2022-02-01 16:30:17,159 MainThread measure_a=0
2022-02-01 16:30:17,159 MainThread measure_b=0
2022-02-01 16:30:17,159 MainThread short pause
2022-02-01 16:30:18,160 MainThread measure_a=0
2022-02-01 16:30:18,160 MainThread measure_b=0
2022-02-01 16:30:18,160 MainThread short pause
现在,这些程序并没有阻碍价值观的解读。
这是简单的线程处理,不需要花哨的“异步多处理”。
https://stackoverflow.com/questions/70939351
复制相似问题