调用​​terminate​​()相当于向进程发送SIGTERM信号

import os,sys
import time
import signal
import multiprocessing

def helper(queue,data):
def signal_handler(signum, frame):
print("son,Killing subprocess")
sys.exit()

signal.signal(signal.SIGTERM, signal_handler)
while True:
print("son,I am working,id=%s,data=%s"%(os.getpid(),str(data)))
command = queue.get()
print('son,my command is',command)
time.sleep(2)
queue.task_done()

def make_pro():
queue = multiprocessing.JoinableQueue()
data=[]
p = multiprocessing.Process(target=helper,
args=(queue,data))
p.start()
print('pid is %s,alive=%s',(p.pid,p.is_alive()))
for i in range(1,5):
data.append(i)
queue.put("*"*i)
print('begin to join')
queue.join()
print('consumer process over,begin to kill')
# time.sleep(60) #TODO
# print('over join,begin to kill')
##p.terminate()
os.kill(p.pid, signal.SIGTERM)
print('kill over')
while p.is_alive(): #这个循环判断可以被p.join()代替
print('still alive')
time.sleep(1)
print('alive is false')

if __name__ == '__main__':
make_pro()

根据下图的输出可以,一般的list不能用于进程间通信,若子进程实现了signal.SIGTERM的处理方法,则通过signal.SIGTERM可以使子进程优雅的退出,若子进程没有实现处理

signal.SIGTERM的方法,进程按默认方式退出

多进程编程_外部程序

 =====================面向对象

import os,sys
import time
import signal
import multiprocessing

class multi_process(multiprocessing.Process):
def __init__(self,task_queue):
self.task_queue=task_queue
super(multi_process,self).__init__()
signal.signal(signal.SIGTERM, self.signal_handler)

def signal_handler(self,signum, frame):
print("son,Killing subprocess")
sys.exit()

def run(self):
while True:
print("son,I am working,id=%s"%(os.getpid()))
command = self.task_queue.get()
print('son,my command is',command)
time.sleep(2)
self.task_queue.task_done()


def make_pro():
task_queue = multiprocessing.JoinableQueue()
data=[]
p = multi_process(task_queue)
p.start()
print('pid is %s,alive=%s',(p.pid,p.is_alive()))
for i in range(1,5):
data.append(i)
task_queue.put("*"*i)
print('begin to join')
task_queue.join()
print('consumer process over,begin to kill')
# time.sleep(60) #TODO
# print('over join,begin to kill')
##p.terminate()
os.kill(p.pid, signal.SIGTERM)
print('kill over')
#下面这三句可以用p.join()代替
while p.is_alive():
print('still alive')
time.sleep(1)
print('alive is false')

if __name__ == '__main__':
make_pro()

多进程编程_外部程序_02

 

 ===================

multiprocessing的核心机制是fork,重开一个进程,会将父进程加载过的模块重新加载一遍,因为操作系统自动把当前进程(称为父进程)复制了一份(称为子进程)
subprocess适用于与外部程序交互,调用外部进程

subprocess 用来执行外部命令,是os.fork() 和 os.execve() 的封装,即先fork一个子进程,再运行新的外部程序,子进程不会把父进程的模块加载一遍;
而multiprocessing的原理是fork,fork()调用:调用1次,返回两次--操作系统自动把当前进程(父进程)复制了一份(子进程),然后,分别在父进程和子进程内返回,父进程返回子进程的pid,子进程返回0,即父进程和子进程都在运行。
对于外部调用来说,使用multiprocessing太占资源

subprocess.Popen()父进程开启子进程后,不管其是否结束,直接执行下一步;
subprocess.Call()父进程一直等待到子进程运行结束,再执行下一步