zoukankan      html  css  js  c++  java
  • 多进程编程

     调用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()父进程一直等待到子进程运行结束,再执行下一步

  • 相关阅读:
    正面管教读书笔记 05 当心逻辑后果
    正面管教读书笔记 04 重新看待不良行为
    正面管教读书笔记 03 出生顺序的重要性
    正面管教读书笔记 02 几个基本概念
    正面管教读书笔记 01 正面的方法
    Shiro身份认证异常:Authentication failed for token submission
    springboot项目配置类使用@ConfigurationProperties注解时,提示Spring Boot Configuration Annotation Proessor not found in classpath
    mysql的性能优化简介
    mysql的逻辑架构
    CentOS7环境下yum方式安装MySQL5.7
  • 原文地址:https://www.cnblogs.com/testzcy/p/12599880.html
Copyright © 2011-2022 走看看