zoukankan      html  css  js  c++  java
  • 进程比较基础的内容

    1.创建多进程的两种方式

    1.1 方式一(函数)

    # 方式一
    from multiprocessing import Process
    import time
    
    def test(name):
        print(f"{name}的子进程开始...")
        time.sleep(3)
        print("子进程结束...")
    if __name__ == '__main__':
        p = Process(target=test,args=("xc",)) # 要用元组哦
        p.start()
        # time.sleep(3)
        print("主进程")
    

    1.2 方式二(类)

    # 方式二
    from multiprocessing import Process
    import time
    
    class My(Process):
        def __init__(self,name):
            super().__init__()
            self.name = name
        def run(self):
            print(f"{self.name}的子进程开始...")
            time.sleep(3)
            print("子进程结束...")
    if __name__ == '__main__':
        p = My('xc')
        p.start()
        print("xc的主进程")
    

    2.孤儿进程和僵尸进程

    • 孤儿进程:其实就是主继承执行完了,子进程还没执行完,因为会变成僵尸进程,以及占用pid号,所以就会被init方法回收
    • 僵尸进程:其实就是子进程运行完了之后,他不是真正的运行完,而是会保留一些信息,其中pid是最主要的信息,僵尸进程,会在主程序执行完了之后被自动回收

    3.pid,一个进程的身份证

    from multiprocessing import Process
    import time
    import os
    
    class My(Process):
        def __init__(self,name):
            super().__init__()
            self.name = name
        def run(self):
            print(f"{self.name}的子进程开始...")
            print(self.pid)
            print(os.getpid())
            print(os.getppid())
            time.sleep(3)
            print("子进程结束...")
    if __name__ == '__main__':
        p = My('xc')
        print(os.getpid())
        p.start()
        print("xc的主进程")
    
    """
    打印结果:
        11200
        xc的主进程
        xc的子进程开始...
        6664
        6664
        11200
        子进程结束...
    """
    
    
    
    • 通过以上数据我们了解了使用os模块的getpid和getppid方法获取进程的pid序号,其中getpid是获取当前进程的pid,而ppid是获取父进程的pid
    • 当然查看pid的方法不止这一个

    4.Process的join方法

    • 等待子进程运行完,在执行主进程的代码,阻塞主程序的运行
    from multiprocessing import Process
    import time
    def foo():
        print("程序开始...")
        time.sleep(3)
        print("程序结束...")
    
    if __name__ == '__main__':
        p = Process(target=foo)
        p1 = Process(target=foo)
        p2 = Process(target=foo)
        start = time.time()
        p.start()
        p1.start()
        p2.start()
        p.join()     # 会阻塞主程序的运行
        p1.join()
        p2.join()
        end = time.time()
        print("主程序结束...")
        print(start-end)
    # 打印结果:
        # 程序开始...
        # 程序结束...
        # 程序开始...
        # 程序开始...
        # 程序结束...
        # 程序结束...
        # 主程序结束...
        # -3.150564193725586
    # 如果表示形式为以上的AAABBB形式,那么所需的时间为3s以上,说明这种写法是主程序等待所有都在运行的子程序执行完
    
    ###################################################################################################
    
    from multiprocessing import Process
    import time
    def foo():
        print("程序开始...")
        time.sleep(3)
        print("程序结束...")
    
    if __name__ == '__main__':
        p = Process(target=foo)
        p1 = Process(target=foo)
        p2 = Process(target=foo)
        start = time.time()
        p.start()
        p.join()  # 会阻塞主程序的运行
        p1.start()
        p1.join()
        p2.start()
        p2.join()
        print("主程序结束...")
        end = time.time()
        print(start-end)
    # 打印结果:
        # 程序开始...
        # 程序结束...
        # 程序开始...
        # 程序结束...
        # 程序开始...
        # 程序结束...
        # 主程序结束...
        # -9.349010705947876
    # 根据上面的内容来看,如果按照ABABAB执行,就会出现子程序等其他子程序执行完再执行,就会叠加时间,就是一个串行的进程了
    
    
    

    5.Process的name和is_alive方法

    • name:查看子进程的名字(类似于这样的名字,Process-1)
    • is_alive:返回值为布尔类型,判断子进程是否结束,需要一定的结束时间,所以使用time模块等一会儿,或者使用join方法等待结束,如果还没结束就返回True,结束了就返回False
    from multiprocessing import Process
    import time
    
    def foo():
        print("进程开始...")
        time.sleep(3)
        print("进程结束...")
    
    if __name__ == '__main__':
        p = Process(target=foo)
        # print(p.is_alive())
        p.start()
        print(p.name)
        print(p.is_alive())
        time.sleep(5)
        print("主程序结束...")
        print(p.is_alive())
    
    # 自己试验下,情况就是name这个属性对应着创建线程的一个代号,它是往下迭代的例如:Process-1,Process-2这样迭代
    
    # 关于is_alive则是表示子程序有没有结束,主要是看子程序有没有运行完,可以使用time模块测试
    
    
    
    

    6.Process的terminal

    • 强制结束子进程(类似于start,是给操作系统信号,并不是直接结束)
    from multiprocessing import Process
    import time
    
    def foo():
        print("进程开始...")
        time.sleep(3)
        print("进程结束...")
    
    if __name__ == '__main__':
        p = Process(target=foo)
        p.start()
        print(p.is_alive())
        p.terminate()  # 强制结束子进程
        p.join() # 我们必须在这里使用join,等待进程结束,那就有人问了,你等他结束了is_alive肯定是Flase呀,但是我们的注意点是子程序没有打印数据
        print(p.is_alive())
        print("主进程结束...")
    
    # 对于Process中的terminate的使用也和start一样,他只是去给操作系统发送了关闭子进程的信号,并不是直接结束
    
    

    7.守护进程

    • 忠心耿耿的进程,通过 对象名.daemon = True 的方法定义一个守护进程.
    from multiprocessing import Process
    import time
    """
    守护进程
    守护 --> 伴随
    本质上也是一个子进程
    主进程的代码执行完毕守护进程直接结束,但是此时主进程可能没有结束
    """
    def foo():
        print("守护进程开始...")
        time.sleep(3)
        print("守护进程结束...")
    
    if __name__ == '__main__':
        p = Process(target=foo)
        p.daemon = True # 这个就是把创建的子进程定义为守护进程,默认值应该是Flase
        p.start()
        # p.join()
        time.sleep(2)
        print("主进程结束...") # 也就是说主进程结束了,子进程就自动释放了,就是不会运行了
    
    # 总结就是daemon这个方法把创建的子进程定义为守护进程,所谓的守护进程就是:主进程结束了,子进程也就是守护进程结束了
    # 如果主进程没结束,子进程也就是守护进程便会像普通进程一样从有到无,从出现到离开
    # 普通的子进程是不会管主进程的死活的,大不了变成孤儿进程继续运行,反正会有init方法回收
    
    
    
  • 相关阅读:
    【数学】Codeforces Round #470 (Div2) B
    【数学】At Coder 091 D题
    【2-SAT】The Ministers’ Major Mess UVALive – 4452
    【二分答案+2-SAT】Now or later UVALive
    【栈模拟dfs】Cells UVALive
    浅谈2-SAT(待续)
    【交叉染色法判断二分图】Claw Decomposition UVA
    【拓扑排序或差分约束】Guess UVALive
    【欧拉回路】UVA
    周总结8.15
  • 原文地址:https://www.cnblogs.com/xiongchao0823/p/11515090.html
Copyright © 2011-2022 走看看