Пусть две функции периодически запускаются с разным временем выборки - PullRequest
1 голос
/ 31 октября 2019

Мне уже удалось периодически выполнять одну функцию с определенным временем выборки T с помощью планировщика python из пакета sched:

import sched
import time

def cycle(sche, T, fun, arg):
    sche.enter(T, 1, cycle, (sche, T, fun, arg))
    fun(arg)


def fun(arg):
    print(str(time.time()))
    print(arg)


def main():
    scheduler = sched.scheduler(time.time, time.sleep)
    T = 1
    arg = "some argument"
    cycle(scheduler, T, fun, arg)
    scheduler.run()

Что я хотел бы сделать, это добавить другую функцию fun2(), который также будет периодически выполняться с другим временем выборки T2.

Каков правильный способ сделать это?

1 Ответ

1 голос
/ 01 ноября 2019

Поэтому для меня сработало следующее решение: поскольку у меня будет две задачи, связанные с процессором, я настроил многопроцессорную среду с двумя процессами. Каждый процесс запускает свой собственный планировщик, который запускается «навсегда» со своим собственным временем «выборки».

Что думает об этом подходе кто-либо с большим опытом работы с Python, чем я (я только начал :-D)? По вашему мнению, это вызовет какие-то проблемы?

import time
import multiprocessing
import sched

global schedule1
global schedule2


def fun1(arg):
    print("Im the function that is executed every T1")
    time.sleep(0.05)  # do something for t < T1


def fun2(arg):
    print("Im the function that is executed every T2")
    time.sleep(0.8)  # do something for t < T2


def cycle1(scheduler1, T1, fun, arg):
    global schedule1
    try:
        schedule1.append(scheduler1.enter(T1, 1, cycle1, (scheduler1, T1, fun, arg)))
        fun1(arg)
        scheduler1.run()
    except KeyboardInterrupt:
        for event in schedule1:
            try:
                scheduler1.cancel(event)
            except ValueError:
                continue
        return


def cycle2(scheduler2, T2, fun, arg):
    global schedule2
    try:
        schedule2.append(scheduler2.enter(T2, 1, cycle2, (scheduler2, T2, fun, arg)))
        fun2(arg)
        scheduler2.run()
    except KeyboardInterrupt:
        for event in schedule2:
            try:
                scheduler2.cancel(event)
            except ValueError:
                continue
        return


def main():
    global schedule2
    global schedule1

    schedule2 = []
    schedule1 = []

    scheduler1 = sched.scheduler(time.time, time.sleep)
    scheduler2 = sched.scheduler(time.time, time.sleep)
    T1 = 0.1
    T2 = 1
    list_of_arguments_for_fun1 = []
    list_of_arguments_for_fun2 = []

    processes = []

    # set up first process
    process1 = multiprocessing.Process(target=cycle1, args=(scheduler1, T1, fun1, list_of_arguments_for_fun1))
    processes.append(process1)

    # set up second process
    process2 = multiprocessing.Process(target=cycle2, args=(scheduler2, T2, list_of_arguments_for_fun2, list_of_arguments_for_fun2))
    processes.append(process2)

    process1.start()
    process2.start()

    for process in processes:
        process.join()

    # anything below here in the main() won't be executed


if __name__ == "__main__":
    try:
        start = time.perf_counter()
        main()

    except KeyboardInterrupt:
        print('\nCancelled by User. Bye!')
        finish = time.perf_counter()
        print(f'Finished in {round(finish - start, 2)} second(s)')
...