Найти - Пользователи
Полная версия: Реализации демона
Начало » Python для экспертов » Реализации демона
1 2 3 4
redixin
совсем не обязательно плодить треды, есть замечательная штука сигналы, и есть замечательный сигнал 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)
Saff
redixin, опиши плз поподробнее.
Saff
На основе примера 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…”
Вопрос в том, насколько корректно, и +не совсем понимаю, поток после исполнения уничтожается?Если нет, то как этим управлять?
redixin
Saff
redixin, опиши плз поподробнее.
signal.signal() ставит обработчик на сгнал SIGALRM функцию job
signal.alarm(1) дает операционке команду “прислать мне сигнал SIGALRM через 1 секунду”

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

в основной программе можно просто слушать сокет, и по требованию вызывать туже функцию job или любую другую. или вообще делать все что угодно, и обработки сигналов проходят незаметно для основной программы. на этих алармах обычно все такое и делается. проще не придумаешь. в винде не работает, там нада както по-другому.
ZAN
После того, как выполнение кода завершается, тред умирает сам - уничтожать его не нужно. Однако, иногда возникает необходимость прибить тред извне, не дожидаясь окончания выполнения кода. Но тут, к сожалению, оказывается, что в питоновском 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())
ZAN
Да, лучше пофикси в сообщениях {code} … {/code} на {code:python} … {/code}, чтобы код отображался с подстветкой -> http://python.com.ua/forum/viewtopic.php?id=49
Saff
Спасибо за ответ, всё понял ))) Есть ещё вопрос: возможно ли иметь доступ к созданным потокам, ну например если я хочу посмотреть статус выполнения задачи этим потоком?
ZAN
Коммуникацию потоков можно осуществлять посредством использвания 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
Saff
Ок, спасибо!Так и зделаю!
cybergrind
isAlive
+ можно передать ссылки на внешние параметры, которые проверять другим процессом
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB