RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 1226413
Accepted
Yuriy Tigiev
Yuriy Tigiev
Asked:2022-01-02 19:27:22 +0000 UTC2022-01-02 19:27:22 +0000 UTC 2022-01-02 19:27:22 +0000 UTC

并行启动具有不同参数的预定函数

  • 772

如何在 python > 3.8 中实现计划函数的并行启动,但使用不同的参数,以便脚本不绑定到操作系统的版本?

下面是一个示例配置文件。python 脚本将读取配置,然后根据配置中指定的频率,它应该以并行模式运行具有指定参数的 fnc 函数。例如,如果用户在 config 中指定了参数 1m, 1h, 1d,那么在每天的 00:00:00,具有参数 fnc(timeframe = 1m), fnc(timeframe = 1h), fnc( timeframe = 1d) 应该并行执行。如何以最优化和正确的方式实现给定的功能?

.ini 文件

1m:fnc(timeframe = 1m)
5m:fnc(timeframe = 5m)
1h:fnc(timeframe = 1h)
4h:fnc(timeframe = 4h)
1d:fnc(timeframe = 1d)
1w:fnc(timeframe = 1w)
python
  • 2 2 个回答
  • 10 Views

2 个回答

  • Voted
  1. Best Answer
    eri
    2022-01-04T22:12:03Z2022-01-04T22:12:03Z

    例如,您可以依靠单调的计时器asyncio进行concurrent.futures.Executor并行化。

    import asyncio
    import datetime
    import time
    import re
    import concurrent.futures
    
    tab = """
    1m:fnc(timeframe = 1m)
    5m:fnc(timeframe = 5m)
    1h:fnc(timeframe = 1h)
    4h:fnc(timeframe = 4h)
    1d:fnc(timeframe = 1d)
    1w:fnc(timeframe = 1w)
    """
    
    TIMEZONE = 3*60
    ms = {
      'm':1,
      'h':60,
      'd':24*60,
      'w':7*24*60
    }
    
    
    def fnc(**args):
        print(datetime.datetime.now(), args)
    
    
    def dispatcher(loop, pool, crontab):
        time_seconds = time.time()
        delay_seconds = (time_seconds//60+1) * 60 - time_seconds
        loop.call_later(delay_seconds, dispatcher, loop, pool, crontab)
        minute = time_seconds // 60 + TIMEZONE
        for interval, callback, name, value in crontab:
            if minute % interval == 0:
                pool.submit(callback, **{name: value})
    
    
    def get_crontab():
        reg = re.compile("([0-9][mhdw]*):([a-z]*)\(([a-z][a-z0-9]*).*([0-9][mhdw]*)\)", re.M)
        crontab = [list(line) for line in reg.findall(tab)]
            
        for line in crontab:
            v,m = re.match(r'([0-9]*)([mhdw])', line[0]).groups()
            v = int(v)
            m = ms[m]
            line[0] = v * m
            line[1] = globals()[line[1]]
        return crontab
    
    
    pool = concurrent.futures.ThreadPoolExecutor(max_workers=5)
    loop = asyncio.get_event_loop()
    dispatcher(loop, pool, get_crontab())
    loop.run_forever()
    

    在我的电脑上,时钟的延迟结果在 0.003-0.060 秒的范围内

    get_crontab - 将示例文本中的格式转换为列表:间隔、函数、参数、值。

    pool 是 5 个线程,它们几乎同时运行这些函数。ProcessPoolExecutor如果要跨所有内核卸载,请替换为。

    loop 是一个异步循环,在这种情况下,它从系统内核接收单调定时器信号。

    调度程序 - 首先安排自己在下一分钟的 00 秒执行。然后它将执行列表中应在当前分钟内执行的功能。

    pool.submit - 在池线程之一中并行运行该函数。

    竞争选项(不是并行的,而是异步的)

    import asyncio
    import datetime
    import time
    import re
    import concurrent.futures
    import inspect
    import functools
    
    tab = """
    1m:fnc(timeframe = 1m)
    5m:fnc(timeframe = 5m)
    1h:fnc(timeframe = 1h)
    4h:fnc(timeframe = 4h)
    1d:fnc(timeframe = 1d)
    1w:fnc(timeframe = 1w)
    """
    
    TIMEZONE = 3*60
    ms = {
      'm':1,
      'h':60,
      'd':24*60,
      'w':7*24*60
    }
    
    
    async def fnc(**args):
        print(datetime.datetime.now(), args)
    
    
    def dispatcher(loop, crontab):
        time_seconds = time.time()
        delay_seconds = (time_seconds//60+1) * 60 - time_seconds
        loop.call_later(delay_seconds, dispatcher, loop, crontab)
        minute = time_seconds // 60 + TIMEZONE
        if time_seconds % 60 > 5:
            return 
        for interval, callback, name, value in crontab:
            if minute % interval == 0:
                if inspect.iscoroutinefunction(callback):
                    loop.create_task(callback(**{name: value}))
                elif inspect.isfunction(callback):
                    loop.call_soon(functools.partial(callback, **{name: value}))
    
    
    def get_crontab():
        reg = re.compile("([0-9][mhdw]*):([a-z]*)\(([a-z][a-z0-9]*).*([0-9][mhdw]*)\)", re.M)
        crontab = [list(m) for m in reg.findall(tab)]
            
        for line in crontab:
            v,m = re.match(r'([0-9]*)([mhdw])', line[0]).groups()
            v = int(v)
            m = ms[m]
            line[0] = v * m
            line[1] = globals()[line[1]]
        return crontab
    
    
    async def main():
        dispatcher(loop, get_crontab())
    
    loop = asyncio.get_event_loop()
    loop.run_until_complete(main())
    loop.run_forever()
    
    • 5
  2. eri
    2022-01-04T23:43:28Z2022-01-04T23:43:28Z

    选项通过time.sleep和multiprocessing

    import multiprocessing
    import datetime
    import time
    import re
    
    
    tab = """
    1m:fnc(timeframe = 1m)
    5m:fnc(timeframe = 5m)
    1h:fnc(timeframe = 1h)
    4h:fnc(timeframe = 4h)
    1d:fnc(timeframe = 1d)
    1w:fnc(timeframe = 1w)
    """
    
    TIMEZONE = 3*60
    ms = {
      'm':1,
      'h':60,
      'd':24*60,
      'w':7*24*60
    }
    
    
    def fnc(**args):
        print(datetime.datetime.now(), args)
    
    
    def dispatcher(pool, crontab, time_seconds):
        minute = time_seconds // 60 + TIMEZONE
        for interval, callback, name, value in crontab:
            if minute % interval == 0:
                pool.apply_async(callback, kwds={name: value})
    
    
    def get_crontab():
        reg = re.compile("([0-9][mhdw]*):([a-z]*)\(([a-z][a-z0-9]*).*([0-9][mhdw]*)\)", re.M)
        crontab = [list(m) for m in reg.findall(tab)]
            
        for line in crontab:
            v,m = re.match(r'([0-9]*)([mhdw])', line[0]).groups()
            v = int(v)
            m = ms[m]
            line[0] = v * m
            line[1] = globals()[line[1]]
        return crontab
    
    pool = multiprocessing.Pool()
    crontab =  get_crontab()
    
    
    while True:
        time_seconds = time.time()
        dispatcher(pool, crontab, time_seconds)
        delay_seconds = (time_seconds//60+1) * 60 - time.time()
        time.sleep(delay_seconds)
    
    
    pool.terminate()
    pool.join()
    
    • 4

相关问题

  • 是否可以以某种方式自定义 QTabWidget?

  • telebot.anihelper.ApiException 错误

  • Python。检查一个数字是否是 3 的幂。输出 无

  • 解析多个响应

  • 交换两个数组的元素,以便它们的新内容也反转

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    表格填充不起作用

    • 2 个回答
  • Marko Smith

    提示 50/50,有两个,其中一个是正确的

    • 1 个回答
  • Marko Smith

    在 PyQt5 中停止进程

    • 1 个回答
  • Marko Smith

    我的脚本不工作

    • 1 个回答
  • Marko Smith

    在文本文件中写入和读取列表

    • 2 个回答
  • Marko Smith

    如何像屏幕截图中那样并排排列这些块?

    • 1 个回答
  • Marko Smith

    确定文本文件中每一行的字符数

    • 2 个回答
  • Marko Smith

    将接口对象传递给 JAVA 构造函数

    • 1 个回答
  • Marko Smith

    正确更新数据库中的数据

    • 1 个回答
  • Marko Smith

    Python解析不是css

    • 1 个回答
  • Martin Hope
    Alexandr_TT 2020年新年大赛! 2020-12-20 18:20:21 +0000 UTC
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5