zoukankan      html  css  js  c++  java
  • 进程与子进程补漏及守护进程与互斥锁的概念

    1.上节课补漏

    把原来在父进程中串行的任务分配到子进程中,实现并发。
    看下上节课复习例题
    子进程方式二的run()固定的
    进程id号是一个进程在操作系统里的身份证号
    僵尸进程:占据pid未回收,其他系统资源回收了
    join()里面有wait 等到子进程执行完毕,将子进程占用操作系统的pid回收
    开启一个子进程时会给他一个pid,回收的是操作系统所占的pid号,而不是子进程属性里的pid,子进程结束后依然可以查看他的pid。

    from multiprocessing import Process
    import time
    import os
    
    def task():
        print('%s is running' %os.getpid())
        time.sleep(3)
        print('%s is done' % os.getpid())
    
    if __name__ == "__main__":
        p=Process(target=task)
        p.start() # 仅仅只是向操作系统发送一个开启进程的信号
        print(p.pid)
    
        p.join() # 等到子进程p执行完毕后,将p占用的操作系统的pid回收
        time.sleep(2)
        print(p.pid) # 依然可以查看他的pid 回收的是他在操作系统所占的pid号 他自己属性里也有
    
    
        print('')
    子进程回收以后pid查看

    僵尸进程目的:为了让父进程随时可以拿到子进程pid。
    出现大量僵尸进程处理:直接杀死父进程
    谁开了谁就是他的父进程:比如cmd运行一个py文件 cmd就是父进程
    杀死父进程cmd,父进程cmd并未关闭窗口是因为cmd被当作终端在输出,如何关闭?

    2.守护进程
    一定要放在p.start()之前
    守护进程其实就是一个“子进程”,
    守护=》伴随
    守护进程会伴随主进程的代码运行完毕而死掉。

    为何要用守护进程?
    守护:该子进程内的代码在父进程代码运行完毕后就没有存在意义了,就应该将该进程设置为守护进程,会在父进程代码结束后死掉。
    进程:当主进程需要把任务并发出去执行,需要把该任务放到一个子进程里。

    子进程·daemon = True 表示该进程未守护进程,这段代码一定要放在start之前
    from multiprocessing import Process
    import time,os
    
    def task(name):
        print('%s is running' %name)
        time.sleep(3)
    
    if __name__ == '__main__':
        p1=Process(target=task,args=('守护进程',))
        p2=Process(target=task,args=('正常的子进程',))
    
        p1.daemon = True # 一定要放到p.start()之前
        p1.start()
        p2.start()
    
        print('')
    守护进程

    注意:守护进程结束的时间是主进程最后一行代码完全执行完毕,如果有输出就是最后一个字符打印到终端才算结束。

    计算机性能越好,开启子进程速度越快,输出可能就不一样,详情见下面的代码。

    #主进程代码运行完毕,守护进程就会结束
    from multiprocessing import Process
    import time
    def foo():
        print(123)
        time.sleep(1)
        print("end123")
    
    def bar():
        print(456)
        time.sleep(3)
        print("end456")
    
    if __name__ == '__main__':
        p1=Process(target=foo)
        p2=Process(target=bar)
    
        p1.daemon=True
        p1.start()
        p2.start()
        print("main-------")
    
        '''
        main-------
        456
        enn456
        '''
    
    
        '''
        main-------
        123
        456
        enn456
        '''
    
        '''
        123
        main-------
        456
        end456
        '''
    不同计算机配置对输出的影响

     



    3.进程的互斥锁
    mutex 互斥的意思 mutex = Lock()
    文件是进程可以共享的
    原理:将并发变成串行,保证数据安全
    互斥锁不能连续acquire,只能release再acquire
    join才是真正的串行
    互斥锁是谁优先抢到锁谁执行共享数据代码,其他部分该并发还是并发。
    互斥锁:可以将要执行部分的任务代码(只涉及到修改共享数据的代码)变成串行。
    join:是要执行任务的所有代码串行。

    mutex.acquire()
    需要串行的程序
    mutex.release()
    被锁起来的程序只能一个个进入。

    #互斥锁:可以将要执行任务的部分代码(只涉及到修改共享数据的代码)变成串行
    #join:是要执行任务的所有代码整体串行
    from multiprocessing import Process,Lock  # 需要导入互斥锁对应的类
    import json
    import os
    import time
    import random
    
    # 模拟抢票的流程:查看票和购买票
    def check():
        time.sleep(1) # 模拟网路延迟
        with open('db.txt','rt',encoding='utf-8') as f:
            dic=json.load(f)
        print('%s 查看到剩余票数 [%s]' %(os.getpid(),dic['count']))
    
    def get():
        with open('db.txt','rt',encoding='utf-8') as f:
            dic=json.load(f)
        time.sleep(2)
        if dic['count'] > 0:
            # 有票
            dic['count']-=1
            time.sleep(random.randint(1,3))
            with open('db.txt','wt',encoding='utf-8') as f:
                json.dump(dic,f)
            print('%s 购票成功' %os.getpid())
        else:
            print('%s 没有余票' %os.getpid())
    
    
    def task(mutex):
        # 查票
        check()
    
        #购票
        mutex.acquire() # 互斥锁不能连续的acquire(获得),必须是release以后才能重新acquire
        get()
        mutex.release()
    
    
    
        # with mutex:  # 可以用这种表达方式,自动释放
        #     get()
    
    if __name__ == '__main__':
        mutex=Lock()
        for i in  range(10):
            p=Process(target=task,args=(mutex,))
            p.start()
            # p.join()
    互斥锁

     









  • 相关阅读:
    Nginx负载均衡+代理+ssl+压力测试
    Nginx配置文件详解
    HDU ACM 1690 Bus System (SPFA)
    HDU ACM 1224 Free DIY Tour (SPFA)
    HDU ACM 1869 六度分离(Floyd)
    HDU ACM 2066 一个人的旅行
    HDU ACM 3790 最短路径问题
    HDU ACM 1879 继续畅通工程
    HDU ACM 1856 More is better(并查集)
    HDU ACM 1325 / POJ 1308 Is It A Tree?
  • 原文地址:https://www.cnblogs.com/Roc-Atlantis/p/9299855.html
Copyright © 2011-2022 走看看