zoukankan      html  css  js  c++  java
  • 锁、信号量

    #模块: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("33[31m第{}个人买不到票33[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()
  • 相关阅读:
    批量计算(batch computing)、流式计算(stream computing)、交互计算(interactive computing)、图计算(graph computing)
    ETL相关 ELT
    添加AD验证(域身份验证)到现有网站
    android开发导包升级到androidx踩坑记录【转载】
    Android Support v4v7v13和AndroidX理解【转载】
    架构师的成长之路初片~linux-基本防护措施
    架构师的成长之路初片~nginx优化篇
    架构师的成长之路初片~linux-监控脚本
    架构师的成长之路初片~Virtual-自定义容器
    架构师的成长之路初片~Virtual-容器和镜像常用的管理命令
  • 原文地址:https://www.cnblogs.com/god-for-speed/p/11719087.html
Copyright © 2011-2022 走看看