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("主程序执行结束。。。")