Найти - Пользователи
Полная версия: Вечный time.sleep() в multiprocessing.Process
Начало » Python для экспертов » Вечный time.sleep() в multiprocessing.Process
1
uchti
Здравствуйте , столкнулся с такой проблемой .
вот примерный код

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() , чтобы гарантировать пробуждение процесса .





uchti
похоже проблема не в коде а в планировщике I/O ядра линукс …
У меня был установлен планировщик deadline. Сейчас я заменил на Completely Fair Queuing (CFQ)
выполнив “echo cfq > /sys/block/sda/queue/scheduler”
После этого проблема пока не замечалась
Soteric
Эту задачу разве не проще решить через очередь и пул потоков? Как-то постоянно засыпать, просыпаться, джойниться, проверять жив ли тред… выглядит сложно :)
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