вот примерный код
class RunRule(Process): def __init__ (self,...,sem): Process.__init__(self) ... self.poolsem=sem def runproc(self,command): try: err='' p=Popen(command,stderr=PIPE,close_fds=True) err=p.stderr.read() p.stderr.close() except ValueError: pass except: self.log.exception("There was a problem.") finally: if p.poll() == None: try: kill(p.pid,SIGKILL) except OSError: pass waitpid(-1, WNOHANG) self.poolsem.release() def processing(self): self.log.info("Start processing") threads=[] while len(self.queue) > 0 and not self.shutdown: while not self.poolsem.acquire(timeout=0.01): for t in threads: t.isAlive() else: command='command' tr=StoppableThread(target=self.runproc,args=(command)) tr.start() threads.append(tr) time.sleep(0.05) self.log.info("Wait while all threads to complete") endtime=int(time.time())+300 sys.setcheckinterval(10) while True: if int(time.time()) > endtime: break if not any([t.isAlive() for t in threads]): break else: time.sleep(1) self.log.info("Stop threads") for t in threads: if t.isAlive(): t.stop() t.join(15) del threads self.log.info("End processing") class ProcQueue(Process): def __init__(self,rule_active_state): Process.__init__(self,name='ProcQueue') self.procrules=[] self.shutdown=False self.sem=BoundedSemaphore(value=config.PROCESSCOUT) def run(self): try: cfg=read_conf() rules_count=len(cfg) if rules_count>0: for line in cfg: bg = RunRule(line[0],int(line[1]),str(line[2]),str(line[3]),str(line[4]),line[5],str(line[6]),str(line[7]),str(line[8]),self.sem) bg.daemon=True bg.start() pid=int(bg.pid) self.log.info("rule pid = %d",pid) self.procrules.append(bg) time.sleep(2) while not self.shutdown: gc.collect() time.sleep(60) except BaseException: self.log.exception("There was a problem.")
работает это так : ProcQueue читает правила из конфига и запускает их через RunRule … правил может быть множество
каждое правило обрабатывает очередь и выполняя внешнюю команду через StoppableThread .
запуск потоков регулируется внешним семофором который объявлен в ProcQueue
суть проблемы : все это работает день может чуть меньше … а затем происходит странное любое из правил может залипнуть и не выполнятся … причем залипает в processing на time.sleep()
раздебажил в gdb
bt
#0 in select () from /lib/x86_64-linux-gnu/libc.so.6
#1 in floatsleep (self=<value optimized out>, args=<value optimized out>)
at ../Modules/timemodule.c:943
залипание происходит когда RunRule процесс менне активно нагружает процесс т.е в его очереди уже отсталость не более 10 элеметнов и он уже заканчивает обработку .
мое предположение : Таск шедулер ubuntu linux просто не доходит до этого процесса и процесс не выходит из спячки
Вопрос : Как разбудить такой процесс ? Или чем заменить time.sleep() , чтобы гарантировать пробуждение процесса .