首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何运行多个需要等待硬件的函数?

如何运行多个需要等待硬件的函数?
EN

Stack Overflow用户
提问于 2022-02-01 10:53:59
回答 1查看 38关注 0票数 -3

嗨,我有一个程序,读取多个传感器,记录和图表的数据。并可根据传感器值启动程序。我的问题是,程序需要等待物理硬件来执行它们的操作。假设我有两个模拟传感器。如果s1的模拟值低于X,则启动P1,需要30秒。如果s2的模拟值低于Y程序,则启动P2,也需要30秒。因此,通过使用睡眠(30),我阻塞了程序的其余部分。因此,我的治疗方法是使用睡眠(1)并记录数据。如果P1仍在运行,而s2低于Y,那么问题就产生了--在这种情况下,我找不到好的解决方案。会不会像异步多处理一样工作。所以在新线程或类似的线程中运行这两个进程。如果是的话,我该怎么做呢?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-02-01 15:31:32

下面是问题的Minimal Reproducible Example

代码语言:javascript
运行
复制
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)
代码语言:javascript
运行
复制
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代码的线程很忙(在本例中它正忙着睡觉)。

解决方案是有多个线程,这样读取值的线程就不会忙着做其他事情了。

代码语言:javascript
运行
复制
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)
代码语言:javascript
运行
复制
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

现在,这些程序并没有阻碍价值观的解读。

这是简单的线程处理,不需要花哨的“异步多处理”。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70939351

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档