Найти - Пользователи
Полная версия: Элегантное завершение программы (kill, linux)
Начало » Python для экспертов » Элегантное завершение программы (kill, linux)
1
Master_Sergius
Имеется макет программного продукта, главный сервис:
file subprocess_threadpool.py
import signal
from subprocess import Popen, PIPE
from time import sleep
 
should_work = True
 
def signal_handler(signum, frame):
    print 'Got signal %s' % (signum,)
    print frame
    global should_work
    should_work = False
    print 'Stopping'
 
signal.signal(signal.SIGTERM, signal_handler)
 
def run_as_subprocess():
    subp = Popen(["python", "test_threadpool.py"], stdout=PIPE)
    output = subp.communicate()[0]
    #print output
 
if __name__ == "__main__":
    while should_work:
        run_as_subprocess()
        sleep(5)
    print 'Parent app done'

И работнички:
file test_threadpool.py
import multiprocessing
import subprocess
from multiprocessing.pool import ThreadPool
from time import sleep
 
def do_calculation(data):
        print "calculating"
        subprocess.call(["logger", "%s - start" % data])
        sleep(20)
        subprocess.call(["logger", "%s - finish" % data])
        return data
 
def test_apply_async():
    inputs = list(range(10))
    print 'Input   :', inputs
    result = []
    for item in inputs:
        result.append(pool.apply_async(do_calculation, args=(item,)))
    print 'Getting result'
    for res in result:
        data = res.get()
        print '\n---\n%s\n%s\n---\n' % (res, data)
        subprocess.call(["logger", "Got result: %s" % data])
 
 
if __name__ == '__main__':
    pool_size = 4
    print pool_size
    pool = ThreadPool(processes=pool_size)
    test_apply_async()
    print "Job done"

Запускаю всё это дело так:
python subprocess_threadpool.py

Теперь когда:
kill $parent_pid
(по pid этого subprocess_threadpool.py), то он логирует “Stopping”, но детишки полностью доделывают свою работу - проходят весь список inputs

Если же:
kill -- -$parent_pid
(получается, по pgid), то логирует “Stopping”, но при этом детишки сразу же прибиваются, в логе имеется к примеру:
Oct 28 00:06:11 xubuntu-laptop sergius: 1 - start
Oct 28 00:06:11 xubuntu-laptop sergius: 0 - start
Oct 28 00:06:11 xubuntu-laptop sergius: 3 - start
Oct 28 00:06:11 xubuntu-laptop sergius: 2 - start

Но нет finish

Мне же надо как-то сделать так, чтобы они выполнили текущую задачу полностью и не проходили весь список. Возможно ли? И как, если возможно?

п.с. пробовал ловить сигнал и во втором скрипте, и делать там pool.terminate(), и тогда логирует finish и вроде как останавливается, но скрипт всегда зависает в цикле сборки результата.
Master_Sergius
В общем, пришлось таки переделывать подход, проблема решена.
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