在多处理中使用信号时执行结果异常.Pool?

时间:2014-04-18 08:26:30

标签: python signals multiprocessing

我正在使用多处理来处理许多文件。为了在cmd中处理ctrl-c并退出正常,我向每个进程添加信号。但它并没有像我期望的那样。

示例代码:

import multiprocessing
from multiprocessing import Pool, Value
from time import sleep
import signal, sys

def f(x):
    p = multiprocessing.current_process()

    if exit_flag:
        s = '%s outer exit' %p.name
        sys.stdout.write(str(s)+'\n')
        return

    for i in range(10):
        if exit_flag:
            s = '%s inner exit' %p.name
            sys.stdout.write(str(s)+'\n')
            break
        s = '%s --- %s' % (i, p.name)
        sys.stdout.write(str(s)+'\n')
        sleep(1)

    if exit_flag:
        s = '%s --- %s final exit' % (i, p.name)
        sys.stdout.write(str(s)+'\n')

def handler(signum, frame):
    global exit_flag
    exit_flag = True

def attach_signal_handler():
    global exit_flag
    exit_flag = False
    signal.signal(signal.SIGINT, handler)
    signal.signal(signal.SIGTERM, handler)

if __name__ == "__main__":
    # attach to main
    attach_signal_handler()
    # change to size = 2, range(6), make result more readable
    size = 2
    pool = Pool(size, attach_signal_handler)  

    for i in range(6):
        result = pool.apply_async(f, (i,))

    pool.close()
    pool.join()

    if result.successful():
        print 'successful'

当我按ctrl+c时,它会打印如下所示的内容。

0 --- PoolWorker-1
0 --- PoolWorker-2
1 --- PoolWorker-1
1 --- PoolWorker-2

(press ctrl +c)

PPoolWorker-2 outer exit
oolWorker-1 outer exit
PPoolWorker-2 outer exit
oolWorker-1 outer exit
successful

inner exitfinal exit未打印,为什么?

我期望的是下面的内容(顺序可能不同,仅举例):

0 --- PoolWorker-1
0 --- PoolWorker-2
1 --- PoolWorker-1
1 --- PoolWorker-2

(press ctrl +c)

PoolWorker-1 inner exit
PoolWorker-1 final exit
PoolWorker-2 inner exit
PoolWorker-2 final exit

(first two processes end at this point)

PoolWorker-2 outer exit
PoolWorker-1 outer exit
PoolWorker-2 outer exit
PoolWorker-1 outer exit

(other four precesses end)    

successful

1 个答案:

答案 0 :(得分:0)

在您点击第一个" if exit_flag:"之后,您的其他条件不会被评估,因为您有return语句,如下代码所示:

    if exit_flag:
        s = '%s outer exit' %p.name
        sys.stdout.write(str(s)+'\n')
        return

    for i in range(10):
        if exit_flag:
            s = '%s inner exit' %p.name
            sys.stdout.write(str(s)+'\n')
            break
        s = '%s --- %s' % (i, p.name)
        sys.stdout.write(str(s)+'\n')
        sleep(1)

    if exit_flag:
        s = '%s --- %s final exit' % (i, p.name)
        sys.stdout.write(str(s)+'\n')

您可以在结尾处简单地移动回报:

    if exit_flag:
        s = '%s outer exit' %p.name
        sys.stdout.write(str(s)+'\n')

    for i in range(10):
        if exit_flag:
            s = '%s inner exit' %p.name
            sys.stdout.write(str(s)+'\n')
            break
        s = '%s --- %s' % (i, p.name)
        sys.stdout.write(str(s)+'\n')
        sleep(1)

    if exit_flag:
        s = '%s --- %s final exit' % (i, p.name)
        sys.stdout.write(str(s)+'\n')
    return