2013-09-02 2 views
0

Ну, моя проблема в следующем. У меня есть сценарий, в котором я хочу запускать 3 функции каждый из них в другом интервале. Все трое имеют ресурс. То, что я сделал следующий (где Рез является общий ресурс):Расписание Python, повторяющее несколько потоков

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) выполняется всегда и на самом деле, не дожидаясь времени, установленного в Таймер. Может ли кто-нибудь помочь, объяснив мне, что я делаю неправильно, и как я могу исправить это?

Заранее спасибо.

+0

Какую версию Python вы используете? Вам не нужны скобки после имен функций? – dwxw

+0

Я использую 2.7. Что касается скобок, см. Обновления. Забыл что-то добавить. – gkaran89

ответ

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 

, так что я не знаю, как вы получили свой код для запуска ...

Вот альтернативный способ делать то, что (I думаю) вы хотите.

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 секунд.

+0

Как я могу повторно использовать потоки, а не создавать новые потоки для каждого момента времени? – xennygrimmato

0

Приведенный ниже код работает для меня. Вы уверены, что #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,)) 
+0

Могло быть только то, что интервал, в котором каждый поток, который я хочу запустить, является динамическим и исходит из части #do части каждой функции. Проверьте обновленный код, пожалуйста. – gkaran89

+0

@ gkaran89 Код обновлен, ваш код исправлен. Надеюсь, что это поможет, но я сомневаюсь. – Germano

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

  • Нет связанных вопросов^_^