• 互斥锁lock、信号量semaphore、事件Event、


    1.互斥锁lock

    应用在多进程中
    互斥所lock:互斥锁是进程间的get_ticket互相排斥
    进程之间,谁先枪占到资源,谁就先上锁,等到解锁之后,下一个进程在继续使用。
    # 语法:
    上锁: lock.acquire()
    解锁: lock.release()

    (1)基本语法

    from multiprocessing import Process,Lock
    
    lock = Lock()
    # 上锁
    lock.acquire()
    print(1)
    # lock.release()  # 如果不解锁,2 就不会打印。
    lock.acquire()
    print(2)
    lock.release()

    (2)模拟抢票

    from multiprocessing import Process
    import json
    
    def wr_info(sign,dic=None):
        if sign == "r":
            with open("ticket.txt" ,mode="r",encoding="utf-8")as fp:
                dic = json.load(fp)
            return dic
        elif sign == "w":
            with open("ticket.txt",mode="w",encoding="utf-8")as fp:
                json.dump(dic,fp)
    
    # 抢票的方法
    def get_ticket(person):
        # 读取数据库中的实际票数
        dic = wr_info("r")
    
        time.sleep(0.1)
        if dic["count"] > 0:
            print("%s 抢票成功 !!"%(person))
            dic["count"] -= 1
            # 更新数据库
            wr_info("w",dic)
        else:
            print("%s抢票失败"%(person))
    # get_ticket("zhangsan")
    # 用ticket来进行统一的函数调用
    def ticket(person,lock):
        # 查询票数
        dic = wr_info("r")
        print("%s查询票数是%s"%(person,dic["count"]))
        # 遇到了acquire上锁之后,进程之间变成同步
        lock.acquire()
        # 开始签票
        get_ticket(person)
        lock.release()
    
    if __name__ == '__main__':
        lock = Lock()
        for i in range(5):
            p = Process(target=ticket,args=("person%s"%(i),lock))
            p.start()

    (3)区分同步和异步

    from multiprocessing import Process
    
    def func(num,lock):
        # 同步上锁
        lock.acquire()
        print(num)
        lock.release()
    if __name__ == "__main__":
        lock = Lock()
        for i in range(10):
            # 异步并发
            p = Process(target=func,args=(i,lock))
            p.start()

    2.信号量semaphore

      本质上就是锁,同一时间可以上多把锁

    # 语法:
    sem = Semaphore(3)
    sem.acquire()
    sem.release()

    (1)基本用法

    import time
    import random
    from multiprocessing import Process,Semaphore
    def ktv(person,sem):
        sem.acquire()
        print("%s进入了ktv,正在唱歌"%(person))
        time.sleep(random.randrange(3,6))
        print("%s唱完了,离开了ktv"%(person))
        sem.release()
    
    if __name__ == "__main__":
        sem = Semaphore(3)
        for i in range(10):
            p = Process(target=ktv,args=("person%s"%(i),sem))
            p.start()

    注意:

    lock 多个进程之间,一次只能上一把锁
    Semaphore 多个进程之间,可以自定义上锁的数量,不限于一个

    3.事件Event

    # 阻塞事件
      e = Event()生成事件对象e
      e.wait()动态给程序加阻塞,程序当中是否加阻塞完全取决与该对象中的is_set()[默认返回值是False]
      # 如果是True,不加阻塞
      # 如果是False 加阻塞
    #控制这个属性的值
      # set()方法 将这个属性的值改成True
      # clear()方法 将这个属性的值改成False
      # is_set()方法 判断当前的属性是否为True (默认上来是False)

    (1)基本语法

    from multiprocessing import Process,Event
    e = Event() # 实例化,生成对象e
    print(e.is_set()) # 查看对象e中的is_set()是True还是False。默认是False
    e.wait() # 加阻塞。is_set()是False
    print(1)
    
    # (2)
    e = Event()
    e.set() # 将is_set() 改成True
    e.wait() # 不加阻塞
    print(3)
    
    e.clear() # 把True=>False
    e.wait()
    print(444)

    (2)红绿灯

    import time,random
    from multiprocessing import Process,Event
    def traffic_light(e):
        # 默认红灯亮
        print("红灯亮")
        while True:
            if e.is_set():
                # 让绿灯亮1秒钟
                time.sleep(1)
                #切换红灯亮
                print("红灯亮")
                # 把True改成False
                e.clear()
            else:
                # 让红灯亮1秒钟
                time.sleep(1)
                # 切换成绿灯亮
                print("绿灯亮")
                # 把默认值从False改成True
                e.set()
    
    def car(e,i):
        # 判断如果是红灯亮,就执行下面代码
        if not e.is_set():
            print("car%s 在等待"% (i))
            e.wait()
        print("car%s通行了"%(i))
    
    """
    # 方法一
    if __name__ == "__main__":
        e = Event()
        # 创建交通灯对象
        p1 = Process(target=traffic_light,args=(e,))
        p1.start()
    
        # 创建小车
        for i in range(10):
            time.sleep(random.randrange(0,2))
            p2 = Process(target=car,args=(e,i))
            p2.start()
    
    """
    
    # 方法二: 优化红绿灯代码[当小车执行结束的时候,把红绿灯终止]
    if __name__ == '__main__':
        lst = []
        e = Event()
        # 创建交通灯对象
        p1 = Process(target=traffic_light,args=(e,))
        p1.daemon=True
        p1.start()
    
        # 创建小车
        for i in range(20):
            time.sleep(random.randrange(0,2))
            p2 = Process(target=car,args=(e,i))
            p2.start()
    
        # 等所有小车通行之后,关闭守护程序
        for i in lst:
            i.join()
    
        print("主程序执行结束。。。")
  • 相关阅读:
    高斯过程回归
    第一行代码读书笔记3+错误分析
    多项式各种操作
    [BZOJ3625] [Codeforces Round #250]小朋友和二叉树
    [BZOJ2055] 80人环游世世界
    [BZOJ3698] XWW的难题
    [BZOJ3456] 城市规划
    分治FFT
    [BZOJ5306] [HAOI2018]染色
    [BZOJ3380] [USACO2004 Open]Cave Cows 1 洞穴里的牛之一
  • 原文地址:https://www.cnblogs.com/youhongliang/p/11862862.html
Copyright © 2020-2023  润新知