Расписание Python, повторяющее несколько потоков
Ну, моя проблема заключается в следующем. У меня есть сценарий, в котором я хочу запустить 3 функции, каждая из которых в различном интервале. Все трое делятся ресурсом. Я сделал следующее (где res - общий ресурс):
import threading
import thread
lock = threading.Lock()
def f1(res) :
lock.acquire()
# do stuff
time = 10.0 # this one changes each time f1 runs
lock.release()
threading.Timer(time,f1).start()
def f2(res) :
lock.acquire()
# do stuff
time = 8.0 # this one changes each time f2 runs
lock.release()
threading.Timer(time,f2).start()
def f3(res) :
lock.acquire()
# do stuff
time = 8.0 # this one changes each time f3 runs
lock.release()
threading.Timer(time,f3).start()
thread.start_new_thread(f1(res))
thread.start_new_thread(f2(res))
thread.start_new_thread(f3(res))
Когда я выполняю код, происходит то, что только первый поток (f1) выполняется вечно и фактически без ожидания времени, установленного в таймере. Может ли кто-нибудь помочь, объяснив мне, что я делаю неправильно и как я могу исправить это?
Заранее спасибо.
2 ответа
Когда я выполняю код, происходит то, что только первый поток (f1) выполняется вечно и фактически без ожидания времени, установленного в таймере.
Похоже, что первый поток запущен, он порождает новый поток таймера, и должно быть join
там, что не позволяет исходному потоку завершиться, пока не завершится его подпоток. Поскольку этот подпоток порождает подпоток и т. Д., Исходный поток никогда не заканчивается.
Тот факт, что выполняется только f1, может быть потому, что в этой строке
thread.start_new_thread(f1(res))
внутренний аргумент f1(res)
оценивается до того, как его возвращаемое значение передается thread.start_new_thread
, Итак, вы на самом деле звоните f1(res)
сначала из основного потока, не порождая поток для вызова f1
,
Нет необходимости использовать thread
Модуль здесь. Вы можете делать все, что вам нужно, с высокоуровневым интерфейсом, предоставляемым threading
модуль. Кроме того, линия
thread.start_new_thread(f1(res))
поднимает
TypeError: start_new_thread expected at least 2 arguments, got 1
так что я не уверен, как вы получили свой код для запуска...
Вот альтернативный способ сделать то, что (я думаю) вы хотите.
import threading
import logging
logger = logging.getLogger(__name__)
lock = threading.Lock()
def f1():
with lock:
logger.info('f1')
threading.Timer(10, f1).start()
def f2():
with lock:
logger.info('f2')
threading.Timer(8, f2).start()
def f3():
with lock:
logger.info('f3')
threading.Timer(23, f3).start()
if __name__ == '__main__':
logging.basicConfig(level=logging.DEBUG,
format='[%(asctime)s %(threadName)s] %(message)s',
datefmt='%H:%M:%S')
threading.Thread(target=f1).start()
threading.Thread(target=f2).start()
threading.Thread(target=f3).start()
который печатает что-то вроде:
[10:53:12 Thread-1] f1
[10:53:12 Thread-3] f2
[10:53:12 Thread-4] f3
[10:53:20 Thread-5] f2
[10:53:22 Thread-2] f1
[10:53:28 Thread-7] f2
[10:53:32 Thread-8] f1
[10:53:35 Thread-6] f3
[10:53:36 Thread-9] f2
C-c C-\Quit
Отметка времени показывает, что f1 запускается каждые 10 секунд, f2 каждые 8 секунд и f3 каждые 23 секунды.
Код ниже работает для меня. Вы уверены, что #do stuff
в f1
не виновник?
import threading
import thread
lock = threading.Lock()
def f1(res) :
lock.acquire()
print "F1"
lock.release()
threading.Timer(1.0,f1, [res]).start()
def f2(res) :
lock.acquire()
print "F2"
lock.release()
threading.Timer(2.0,f2, [res]).start()
def f3(res) :
lock.acquire()
print "F3"
lock.release()
threading.Timer(3.0,f3, [res]).start()
thread.start_new_thread(f1, (res,))
thread.start_new_thread(f2, (res,))
thread.start_new_thread(f3, (res,))