多进程编程

 调用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()

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

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

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


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

原文地址:https://www.cnblogs.com/testzcy/p/12599880.html