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()
    互斥锁

     









  • 相关阅读:
    编译asp.net core源代码,并搭建基于源代码的测试环境
    sql server 按照in里面的顺序进行查询
    j-roadflow-java工作流修改抄送任务已阅知表单为只读
    roadflow工作流用nginx做负载均衡的配置文件
    vue ie 报错SCRIPT5022: SecurityError sockjs.js (1683,3)
    RoadFlow Asp.net Core Vue工作流引擎增加对PostgreSQL数据库的支持
    点,线,面
    .NET 5应用程序中的跨域请求
    物料齐套计算
    高级计划AP(Advance Planning)是如何运作的 (转载)
  • 原文地址:https://www.cnblogs.com/Roc-Atlantis/p/9299855.html
Copyright © 2011-2022 走看看