multiprocessing.Manager()启动一个子进程,该子进程负责处理您的共享列表代理。
运行时的netstat输出:
UNIX 2 [ACC]流侦听3921657 8457 / python / tmp / pymp-B9dcij / listener-X423Ml
这个由multiprocessing.Manager()创建的子进程正在捕获您的SIGINT并退出,从而导致与它相关的任何事物都被取消引用,因此出现“无此类文件”错误(根据我决定发送SIGINT的时间,我还会遇到其他一些错误)。
为了解决这个问题,您可以直接声明一个SyncManager对象(而不是让Manager()为您完成)。这将需要您使用start()方法来实际启动子进程。start()方法将初始化函数作为其第一个参数(您可以在此处为管理器覆盖SIGINT)。
下面的代码,尝试一下:
from multiprocessing import Process, Manager
from multiprocessing.managers import BaseManager, SyncManager
from time import sleep
import signal
#handle SIGINT from SyncManager object
def mgr_sig_handler(signal, frame):
print 'not closing the mgr'
#initilizer for SyncManager
def mgr_init():
signal.signal(signal.SIGINT, mgr_sig_handler)
#signal.signal(signal.SIGINT, signal.SIG_IGN) # <- OR do this to just ignore the signal
print 'initialized mananger'
def f(process_number, shared_array):
try:
print "starting thread: ", process_number
shared_array.append(process_number)
sleep(3)
shared_array.append(process_number)
except KeyboardInterrupt:
print "Keyboard interrupt in process: ", process_number
finally:
print "cleaning up thread", process_number
if __name__ == '__main__':
processes = []
#using syncmanager directly instead of letting Manager() do it for me
manager = SyncManager()
manager.start(mgr_init) #fire up the child manager process
shared_array = manager.list()
for i in xrange(4):
p = Process(target=f, args=(i, shared_array))
p.start()
processes.append(p)
try:
for process in processes:
process.join()
except KeyboardInterrupt:
print "Keyboard interrupt in main"
for item in shared_array:
print item