异步的三大机制

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()
原文地址:https://www.cnblogs.com/ljc-0923/p/9632567.html