• 异步的三大机制


    1,锁机制(在异步进程的时候,多个子进程访问同一个资源时,会有数据混乱的情况)

    from multiprocessing import Lock
    l = Lock()  # 实例化一个锁的对象
    l.acquire()  # 拿走钥匙,锁门,不让其他人进屋(当有一个进程访问数据的时候.不允许其他进程访问)
    l.release()  # 释放锁,还钥匙,开门,允许其他人进屋(当上一个进程访问完这个数据的时候,才会让下一个数据进行访问)
    from multiprocessing import Process, Lock,Value
    import time
    def get_money(num, l):  # 取钱的进程
        l.acquire()  # 获取num数据的钥匙(把num的资源独自享有,不允许别的进程访问)
        for i in range(100):
            num.value -= 1
            print("取钱:%s"%mun.value)
            time.sleep(0.1)
            l.release()  # 等此子进程操作完毕后归还钥匙(是释放num的资源)
            
            
    def put_money(num, l):
        l.acquire()  # 只有上一个子进程归还了钥匙(释放了公共资源)获取数据的钥匙
        for i in range(100):
            num.value += 1
            print("存钱:%s"%num.value)
            time.sleep(0.1)
            l.release()
            
            
    if __name__ == "__main__":
        num = Value("i", 100)
        l = Lock()  # 实例化锁的对象(Lock其实是一个类)
        p = Process(target=get_money,args=(num,l))  # 实例化的对象然后开启子进程的函数时指定的,其他的没有,有且只有本函数一个
        p.start()  # 开启一个子进程
        p1 = Process(target=put_money,args=(num,l))
        p.join()  # 等待这个子进程结束以后再执行主程序
        p1.join()  # 同理
        time.sleep(0.1)
        print(num.value)
    • 1.2>模仿网络购票
    from multiprocessing import Process,Lock
    import time
    def check_ticket(i):
        with open("Spare_ticket") as f:
            content = f.read()
            print("第%s个人查余票了,还剩%s张"%(i,content))
            time.sleep(0.1)
    def buy_ticket(i,l):
        l.acquire()  # 所的机制是一次只能一个人购票(进程访问)
        with open("Spare_ticket") as f:
            content = int(f.read())  # 把数据库里的票数读出来
            if content > 0:  # 此时判断数据库里的余票还有多少张
                content -= 1
                print("第%s个人买到票了,还剩%s张票"%(i,content))
            else:
                print("第%s个人没有买到票"%i)
                with open("Spare_ticket","w") as f:   # 在执行完买票以后,把数据库里的数据更改掉
                    f.write(str(content))
                    time.sleep(0.1)
                    l.release()  # 每次一个进程使用完一个被锁着的资源的时候,就会释放这个资源
    if __name__ == "__main__":
        l = Lock()  # 实例化锁的对象
        for i in range(100):
            p1 = Process(target=check_ticket,args=(i,))
            p1.start()
        for i in range(100):
            p2= Process(target=buy_ticket,args=(i,l))
            p2.start()

    2,信号量机制

    • l = Lock()...................实例化一个锁的对象
    • l.acquire()..................获取锁的钥匙
    • l.release()....................释放钥匙(有借有还,在借不难)
    • l = Semaphore(4)..................实例化一个信号量的对象,括号里的参数是锁的几把钥匙,当什么都不写的时候,默认有一把钥匙,写了1也是有一把钥匙,当有四把钥匙的时候,就可以一次4个进程同时访问一个资源,无需前几个释放共有资源,其他有要访问共有资源的时候,就得等到这4个进程完事以后释放资源,在进行访问.
    from multiprocessing import Process,Semaphore
    import time
    import random
    
    
    def func(i,s):
        s.acquire()  # 跟锁是一样的,获取访问公共资源的权限(不过这一次获取的是5个权限)
        print("33[32m这是第%s个人进入小黑屋33[32m"%i)  # 此时有5个进程同时访问共有的资源
        time.sleep(random.randint(3,5))
        print("这是第%s个人离开小黑屋"%i)  # 此时只要有出去的进程就会有进来的进程,直到最后5个进程一起出去(有进有出,反复的一进一出)
        s.release()
        
        
    if __name__ == "__main__":
        s = Semaphore(5)  # 实例化信号量的对象并配发5把钥匙(开5个进程可以访问共有资源的权限)
        for i in range(10):
            p = Process(target=func,args=(i,s))
            p.start()

    3,事件机制

    from multiprocessing import Process,Event
    import time
    import random
    
    def tra(e):
        '''信号灯函数'''
        # e.set()
        # print('33[32m 绿灯亮! 33[0m')
        while 1:# 红绿灯得一直亮着,要么是红灯要么是绿灯
            if e.is_set():# True,代表绿灯亮,那么此时代表可以过车
                time.sleep(5)# 所以在这让灯等5秒钟,这段时间让车过
                print('33[31m 红灯亮! 33[0m')# 绿灯亮了5秒后应该提示到红灯亮
                e.clear()# 把is_set设置为False
            else:
                time.sleep(5)# 此时代表红灯亮了,此时应该红灯亮5秒,在此等5秒
                print('33[32m 绿灯亮! 33[0m')# 红的亮够5秒后,该绿灯亮了
                e.set()# 将is_set设置为True
    
    def Car(i,e):
        e.wait()# 车等在红绿灯,此时要看是红灯还是绿灯,如果is_set为True就是绿灯,此时可以过车
        print('第%s辆车过去了'%i)
    
    if __name__ == '__main__':
        e = Event()
        triff_light = Process(target=tra,args=(e,))# 信号灯的进程
        triff_light.start()
        for i in range(50):# 描述50辆车的进程
            if i % 3 == 0:
                time.sleep(2)
            car = Process(target=Car,args=(i+1,e,))
            car.start()
  • 相关阅读:
    IOS 11 通讯录手机号「隐形字符」的 Bug
    本地添加const参数 防止短信接口恶意调用
    javascript阿拉伯数字 转 汉字中文数字
    js去掉数组的空字符串
    Chrome 清除某个特定网站下的缓存
    vue-cli中的babel配置文件.babelrc详解
    提交到github报错Please tell me who you are
    跨域问题
    js单线程、js任务队列、异步操作
    Java 异常
  • 原文地址:https://www.cnblogs.com/ljc-0923/p/9632567.html
Copyright © 2020-2023  润新知