• 多进程


    获取进程及主进程的pid

    什么是pid

    进程在内存中开启多个,操作系统区分进程的方式就是通过每个进程都有的一个唯一的标识 — pid来区分

    查看pid的方式

    在终端查看当前所有进程的pid

    在cmd窗口中输入tasklist

    在终端查看正在执行的制定名字的进程的pid

    在cmd窗口中输入tasklist|findstr + 进程名字

    通过代码层面查看pid

    os.getpid()  查看子进程

    os.getppid()   查看父进程

    验证进程间的空间隔离

    from multiprocessing import Process
    import time
    x = 1000
    
    def task():
        global x
        x = 2
    
    if __name__ == '__main__':
        p = Process(target=task)
        p.start()
        time.sleep(3)
        print(x)         
    验证进程之间的空间隔离

    join方法

    join:等待,主进程等待子进程结束之后再执行

    from multiprocessing import Process
    import time
    
    def task(name):
        time.sleep(1)
        print(f'{name} is running')
    
    if __name__ == '__main__':
        p = Process(target=task,args=('alex',))
        p.start()
        p.join()  # 告知主进程,p进程结束之后,主进程再运行
        print('主进程执行')
    开启多个子进程去验证:
    
    
    from multiprocessing import Process
    import time
    
    def task(name):
        time.sleep(1)
        print(f'{name} is running')
    
    if __name__ == '__main__':
        p1 = Process(target=task, args=('alex',))
        p2 = Process(target=task, args=('barry',))
        p3 = Process(target=task, args=('wusir',))
        p1.start()
        p2.start()
        p3.start()
        # p1, p2, p3 三个子进程运行的先后顺序不定
        # start只是通知一下操作系统,三个start几乎同一时刻发给操作系统
        # 操作系统调用cpu先运行谁,谁先执行
        print('主进程执行')
    
    
    from multiprocessing import Process
    import time
    
    def task(name,second):
        time.sleep(second)
        print(f'{name} is running')
    
    if __name__ == '__main__':
        p1 = Process(target=task, args=('alex', 1))
        p2 = Process(target=task, args=('barry', 2))
        p3 = Process(target=task, args=('wusir', 3))
        start_time = time.time()
        p1.start()
        p2.start()
        p3.start()
        p1.join() # 视下面代码为主进程,此种写法为并发
        p2.join()
        p3.join()
        print(f'主进程:{time.time() - start_time}之后,执行')
    
    
    from multiprocessing import Process
    import time
    
    def task(name,second):
        print(f'{name} is running')
        time.sleep(second)
        print(f'{name} is done')
    
    if __name__ == '__main__':
        p1 = Process(target=task, args=('alex', 1))
        p2 = Process(target=task, args=('barry', 2))
        p3 = Process(target=task, args=('wusir', 3))
        start_time = time.time()
        p1.start()
        p1.join()  #视下面代码为主进程,此种写法为串行
        p2.start()
        p2.join()
        p3.start()
        p3.join()
        print(f'主进程:{time.time() - start_time}之后,执行')
    join方法

    进程对象的其他属性

    from multiprocessing import Process
    import time
    
    
    def task(name):
    
        print(f'{name} is running')
        time.sleep(3)
        print(f'{name} is done')
    
    
    if __name__ == '__main__':
    
        p = Process(target=task,args=('怼哥',) ,name='任务1')  # name给进程对象设置name属性
        p.start()
        print(p.pid)  # 获取进程pid号
        print(p.name)
        time.sleep(1)
        p.terminate() # 终止(结束)子进程
        # terminate 与 start一样的工作原理: 都是通知操作系统终止或者开启一个子进程,内存中终止或者开启(耗费时间)
        time.sleep(1)
        print(p.is_alive())  # 判断子进程是否存活
        # 只是查看内存中p子进程是否运行.
        print('===主进程')
    进程对象的其他属性

    僵尸进程和孤儿进程

    这是在Linux环境下才强调的两个概念,Windows环境下没有这两个概念

    from multiprocessing import Process
    import time
    import os
    
    def task(name):
    
        print(f'{name} is running')
        print(f'子进程开始了:{os.getpid()}')
        time.sleep(50)
    
    
    if __name__ == '__main__':
        for i in range(100000):
            p = Process(target=task,args=('alex',))
            p.start()
        print(f'主进程开始了:{os.getpid()}')

    僵尸进程

    僵尸进程:一个进程使用fork创建子进程,如果子进程退出,而父进程并没有调用wait或waitpid获取子进程的状态信息,那么子进程的进程描述符仍然保存在系统中。这种进程称之为僵尸进程。

    僵尸进程的内存中只包括主进程的pid,子进程的开始时间,结束时间,至于主进程的代码以及文件,数据库等全部消失。可以利用waitpid()方法对僵尸进程进行“收尸”

    僵尸进程是有害的。僵尸进程如果无限的开启子进程,子进程就会越来越多,占用内存

    孤儿进程

    如果一个主进程退出,而它的一或多个子进程还在运行,那么那些子进程将成为孤儿进程

    孤儿进程是无害的,一段时间后,init会对孤儿进程进行回收

    守护进程

    运行在后台并且只在需要时才唤醒的进程称为守护进程(电子邮件,web网页,新闻,打印等)

    主进程创建守护进程

    守护进程会在主进程代码执行结束后就终止

    守护进程内不能再开启子进程,否则就会抛出异常:AssertionError: daemonic processes are not allowed to have children

    注意:进程之间是互相独立的,主进程代码运行结束,守护进程随即终止

    #主进程代码运行完毕,守护进程就会结束
    from multiprocessing import Process
    from threading import Thread
    import time
    def foo():
        print(123)
        time.sleep(1)
        print("end123")
    
    def bar():
        print(456)
        time.sleep(3)
        print("end456")
    
    
    p1=Process(target=foo)
    p2=Process(target=bar)
    
    p1.daemon=True   #一定要在p.start()前设置,设置p为守护进程,禁止p创建子进程,并且父进程代码执行结束,p即终止运行 
    p1.start()
    p2.start()
    print("main-------") #打印该行则主进程代码结束,则守护进程p1应该被终止,可能会有p1任务执行的打印信息123,因为主进程打印main----时,p1也执行了,但是随即被终止
    守护进程示例代码
  • 相关阅读:
    散列函数之单散列算法
    NET 使用 RabbitMQ
    leetCode
    Swift 1
    C#并发集合
    多进程与多线程1
    开发编译器
    APUE1
    微服务架构
    ExceptionHandlerMiddleware中间件如何呈现“定制化错误页面”
  • 原文地址:https://www.cnblogs.com/biulo/p/11228214.html
Copyright © 2020-2023  润新知