锁、信号量

#模块:Lock
#导入方法:from multiprocessing import Process,Lock
#模块方法:
    l=Lock()
    l.acquire()    #对所访问的资源加锁
    l.release()    #释放锁
#使用方法:一般在需要访问的资源的那部分代码加锁释放锁,但在初学阶段可以先包含整段程序


###########模拟抢票程序
from multiprocessing import Process,Lock
import time
#在进行买票的时候,多个进程间有可能会出现第一个进程虽然先到达了,但是刚好时间片用完,这时候就会使得第一个到达的不一定会先买得到票
#不加锁的话,有可能在打开文件的时候另一个进程也打开了该文件,导致买到票的一个进程中的结果没有保存就被另一个进程所用了,以至于可能造成一张票多个人购买成功的情况
def check(i):
    with open("residue") as f:
        count=int(f.read())         #文件读取时为字符串类型,需要转为整数类型进行判断
        if count>0:
            print("第{}个人查到了余票为{}".format(i,count))
        else:
            print("已经没有票了")

def purchase(i,l):
    #进行加锁操作
    l.acquire()
    with open("residue") as f:
        count = int(f.read())
        time.sleep(0.1)
    if count>0:
        print("第{}个人买到票了".format(i))
        count-=1
    else:
        print("\033[31m第{}个人买不到票\033[1m".format(i))
    time.sleep(0.1)  # 是指 买完票后,把余票数量重写写入数据库的时间延迟
    with open("residue",'w') as f:
        f.write(str(count))  # 写入文件需要以字符串的形式写入文件,所以需要将整数类型进行强制转换为字符串类型
    l.release()

if __name__=="__main__":
    #多个进程查票
    for i in range(1,10):
        p=Process(target=check,args=(i+1,))
        p.start()
    #多个进程进行购票
    #先实例化Lock对象
    l=Lock()
    #再将l以参数的方式传进去
    for i in range(1,10):
        p=Process(target=purchase,args=(i+1,l))
        p.start()
        
        
        
        
###########银行存取钱原理
from multiprocessing import Process,Value,Lock
import time


def get_money(num,l):# 取钱
    l.acquire()# 拿走钥匙,锁上门,不允许其他人进屋
    for i in range(100):
        num.value -= 1
        print(num.value)
        time.sleep(0.01)
    l.release()# 还钥匙,打开门,允许其他人进屋

def put_money(num,l):# 存钱
    l.acquire()
    for i in range(100):
        num.value += 1
        print(num.value)
        time.sleep(0.01)
    l.release()

if __name__ == '__main__':
    num = Value('i',100)
    l = Lock()
    p = Process(target=get_money,args=(num,l))
    p.start()
    p1 = Process(target=put_money, args=(num,l))
    p1.start()
    p.join()
    p1.join()
    print(num.value)

 

 

 

#模块:Semaphore
#导入方法:from multiprocessing import Process,Semaphore
#模块方法:
    sem=Semaphore(i)        #i是一个(房间)允许i个进程进入
    sem.acquire()            #对所访问的资源加锁
    sem.release()            #释放锁
#使用方法:类似于锁
#信号量和锁相似:通俗理解,锁机制是一个房间只能一个进程进去,而信号量机制是一个房间允许i个进程进去
#信号量和锁区别:信号量机制比锁机制多了一个计数器,这个计数器是用来记录当前剩余几把钥匙的。
                 当计数器为0时,表示没有钥匙了,此时acquire()处于阻塞。
                 对于计数器来说,每acquire一次,计数器内部就减1,release一次,计数器就加1


from multiprocessing import Process,Semaphore
import time
import random

def func(i,sem):
    #信号量实现的开始
    sem.acquire()
    print("第{}个人进入".format(i))
    time.sleep(random.randint(3,5))
    print("第{}个人退出".format(i))
    #信号量实现的结束
    sem.release()



if __name__=="__main__":
    #允许count个进程访问资源
    count=5
    sem = Semaphore(count)
    for i in range(10):
        p=Process(target=func,args=(i,sem))
        p.start()

 

posted @ 2019-10-22 12:28  LBC不认输  阅读(315)  评论(0编辑  收藏  举报