2014-02-07 2 views
2

Я боролся с этим вопросом в течение недели, чтобы спросить кого-то, кто может ответить на вопрос через пару минут.Как планировать задачи без выхода из существующего цикла?

Я пытаюсь запустить программу python раз в 10 секунд. Есть много вопросов такого рода: Use sched module to run at a given time, Python threading.timer - repeat function every 'n' seconds, How to execute a function asynchronously every 60 seconds in Python?

Обычно решения с использованием sched или time.sleep будет работать, но я стараюсь, чтобы начать запланированный процесс изнутри cmd2, который уже работает в while False цикле , (Когда вы выходите из cmd2, он выходит из этого цикла).

Из-за этого, когда я запускаю функцию для повторения каждые 10 секунд, я ввожу другой цикл, вложенный в cmd2, и я не могу ввести команды cmd2. Я могу вернуться только до cmd2, выйдя из подцикла, который повторяет функцию, и, таким образом, функция перестает повторяться.

Очевидно, резьба решает эту проблему. Я пробовал threading.Timer без успеха. Возможно, настоящая проблема заключается в том, что я не понимаю потоки или многопроцессорность.

Вот пример кода, который грубо изоморфно код, я использую, используя sched модуль, который я получил на работу:

import cmd2 
    import repeated 

    class prompt(cmd2.Cmd): 
    """this lets you enter commands""" 

     def default(self, line): 
      return cmd2.Cmd.default(self, line) 

     def do_exit(self, line): 
      return True 

     def do_repeated(self, line): 
      repeated.func_1() 

Где repeated.py выглядит следующим образом:

import sched 
    import time 

    def func_2(sc): 
     print 'doing stuff' 
     sc.enter(10, 0, func_2, (sc,)) 


    def func_1(): 
     s = sched.scheduler(time.time, time.sleep) 
     s.enter(0, 0, func_2, (s,)) 
     s.run() 

ответ

1

Как только я задал этот вопрос, я был в состоянии понять это , Не знаю, почему это происходит иногда.

Этот код

def f(): 
    # do something here ... 
    # call f() again in 60 seconds 
    threading.Timer(60, f).start() 

# start calling f now and every 60 sec thereafter 
f() 

Отсюда: How to execute a function asynchronously every 60 seconds in Python?

На самом деле работает для того, что я пытался сделать. Очевидно, есть некоторые тонкости в том, как функция вызывается как аргумент в threading.Timer. Раньше, когда я включал аргументы и даже круглые скобки после функции, я получал рекурсивные ошибки глубины --i.e. функция постоянно вызывала себя.

Так что любой, у кого есть такая проблема, обратите внимание на то, как вы вызываете функцию в threading.Timer(60, f).start(). Если вы напишете threading.Timer(60, f()).start() или что-то подобное, это, вероятно, не сработает.

2

http://docs.python.org/2/library/queue.html?highlight=queue#Queue

Можете ли вы экземпляр объекта очереди за пределами cmd2? Существует один поток, который следит за очередью и периодически выполняет задания из него; в то время как cmd2 может запускаться или не запускаться. Конечно, поток, который обрабатывает очередь, и сам объект очереди должен быть во внешней области.

Чтобы запланировать что-то в определенное время, вы можете вставить кортеж, в котором есть целевое время. Или вы можете проверить поток через регулярные интервалы, если это достаточно хорошо.

[Редактировать, если у вас есть процесс, который предназначен, чтобы повторить, вы можете иметь его снова поставить себя в конце его эксплуатации.]

+0

Спасибо за это, я не знал о очереди. Похоже, он будет делать то, что я ищу. Тем не менее, я нашел более простой способ с threading.Timer (который является предпочтительным способом, судя по количеству ответов, использующих его) и изложил его ниже. – Wapiti

Смежные вопросы