Уведомления

Группа в Telegram: @pythonsu

#1 Апрель 29, 2008 15:05:30

redixin
От:
Зарегистрирован: 2006-11-27
Сообщения: 66
Репутация: +  1  -
Профиль   Отправить e-mail  

Реализации демона

совсем не обязательно плодить треды, есть замечательная штука сигналы, и есть замечательный сигнал SIGALRM

import signal, time
interval = 1
def job(signum, frame):
    print signum, frame
    signal.alarm(interval)
signal.signal(signal.SIGALRM, job)
signal.alarm(interval)
while 1:
    time.sleep(1)



Офлайн

#2 Апрель 29, 2008 15:53:18

Saff
От:
Зарегистрирован: 2008-03-18
Сообщения: 56
Репутация: +  0  -
Профиль   Отправить e-mail  

Реализации демона

redixin, опиши плз поподробнее.



Офлайн

#3 Апрель 29, 2008 16:24:56

Saff
От:
Зарегистрирован: 2008-03-18
Сообщения: 56
Репутация: +  0  -
Профиль   Отправить e-mail  

Реализации демона

На основе примера ZAN'а, получилось вот так:
import threading
import errno
import time
import timeit
import MySQLdb
from threading import Timer
from threading import Event

class TimerDaemon(object):
def start(self, launcher):
self.launcher = launcher
for mstr in self.launcher.taskDict:
self.run_task = mstr
threading.Thread(target=self.handleTime).start()
self.run_task = “”

def handleTime(self):
#print self.run_task
timeit.default_timer()
run_task = self.run_task
while 1:
timeout = self.launcher.launch(run_task)
print ‘total time %s\n’ %timeit.default_timer()
time.sleep(timeout)


class Launcher(object):
def __init__(self):
self.taskDict = {}

def addTask(self, taskName, task):
if hasattr(task, ‘execute’):
self.taskDict = task
else:
raise Exception('object %s is not executable' %task)

def launch(self, taskName):
threading.Thread(target=self.taskDict.execute())
return self.taskDict.timeout

def launch_all(self):
#print “launching”
threading.Thread(target=self.taskDict.execute())

class fileCheck():
timeout = 5
def execute(self):
print “FileCheck!!”
class dbTest():
timeout = 10
def execute(self):
print “DBTEST!!”

if __name__ == ‘__main__’:
launcher = Launcher()

launcher.addTask('fileCheck', fileCheck())
launcher.addTask('dbTest', dbTest())

timerDaemon = TimerDaemon()
timerDaemon.start(launcher)

print “Runinig daemon…”
Вопрос в том, насколько корректно, и +не совсем понимаю, поток после исполнения уничтожается?Если нет, то как этим управлять?



Отредактировано (Апрель 30, 2008 08:58:22)

Офлайн

#4 Апрель 29, 2008 16:38:09

redixin
От:
Зарегистрирован: 2006-11-27
Сообщения: 66
Репутация: +  1  -
Профиль   Отправить e-mail  

Реализации демона

Saff
redixin, опиши плз поподробнее.
signal.signal() ставит обработчик на сгнал SIGALRM функцию job
signal.alarm(1) дает операционке команду “прислать мне сигнал SIGALRM через 1 секунду”

дальше что бы программа не делала, по приходу сигнала SIGALRM - вызывается твоя функция job, после того как она отработала - продолжается выполнение основной программы. не забудь по окончанию обработки сигнала вызвать функцию signal.alarm чтобы через следующую секунду ОС прислала сигнал SIGALRM

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



Офлайн

#5 Апрель 29, 2008 18:47:44

ZAN
От:
Зарегистрирован: 2007-06-10
Сообщения: 403
Репутация: +  10  -
Профиль   Отправить e-mail  

Реализации демона

После того, как выполнение кода завершается, тред умирает сам - уничтожать его не нужно. Однако, иногда возникает необходимость прибить тред извне, не дожидаясь окончания выполнения кода. Но тут, к сожалению, оказывается, что в питоновском threading этого сделать нельзя http://docs.python.org/lib/module-threading.html:

documentation
currently, there are no priorities, no thread groups, and threads cannot be destroyed, stopped, suspended, resumed, or interrupted
В этом случае нужно поступать так, как предложил redixin.
Код же вполне корректен (во всяком случае, мне он кажется вполне таковым =), за исключением двух вещей - метод launch_all использует неинициализированную переменную taskName. А второе - это моя прореха - в методе Launcher.launch нужно запускать метод execute таким образом:
threading.Thread(target=self.taskDict.execute).start()
а не
threading.Thread(target=self.taskDict.execute())



Офлайн

#6 Апрель 29, 2008 18:51:01

ZAN
От:
Зарегистрирован: 2007-06-10
Сообщения: 403
Репутация: +  10  -
Профиль   Отправить e-mail  

Реализации демона

Да, лучше пофикси в сообщениях {code} … {/code} на {code:python} … {/code}, чтобы код отображался с подстветкой -> http://python.com.ua/forum/viewtopic.php?id=49



Офлайн

#7 Апрель 30, 2008 08:57:47

Saff
От:
Зарегистрирован: 2008-03-18
Сообщения: 56
Репутация: +  0  -
Профиль   Отправить e-mail  

Реализации демона

Спасибо за ответ, всё понял ))) Есть ещё вопрос: возможно ли иметь доступ к созданным потокам, ну например если я хочу посмотреть статус выполнения задачи этим потоком?



Офлайн

#8 Апрель 30, 2008 12:15:37

ZAN
От:
Зарегистрирован: 2007-06-10
Сообщения: 403
Репутация: +  10  -
Профиль   Отправить e-mail  

Реализации демона

Коммуникацию потоков можно осуществлять посредством использвания shared объектов. Фактически, в threading роль такого объекта выполняет Event http://docs.python.org/lib/event-objects.html, однако, его функциональность ограничивается внутренним только флагом set. Но по такому же принципу можно создавать свои собственные объекты.
Так как нужно только проверить прогресс выполнения задачи, такой объект можно совместить с выполняющейся таской:
class HelloWorldTask(BaseTask):
def __init__(self):
self.progress = 0

def execute(self):
self.progress = 0
for i in xrange(100):
self.progress += 1
time.sleep(0.1)
print ‘Hello, Worlld!’
В launcher добавится метод проверки степени выполнения задачи:
class Launcher(object):
def checkStatus(taskName):
return self.taskDict.progress



Офлайн

#9 Апрель 30, 2008 16:35:37

Saff
От:
Зарегистрирован: 2008-03-18
Сообщения: 56
Репутация: +  0  -
Профиль   Отправить e-mail  

Реализации демона

Ок, спасибо!Так и зделаю!



Офлайн

#10 Апрель 30, 2008 16:38:40

cybergrind
От:
Зарегистрирован: 2008-01-21
Сообщения: 201
Репутация: +  0  -
Профиль   Отправить e-mail  

Реализации демона

isAlive
+ можно передать ссылки на внешние параметры, которые проверять другим процессом



Отредактировано (Апрель 30, 2008 16:39:48)

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version