信号量和事件

信号量和事件

一、信号量

  • 信号量Semahpore(同线程一样)
  • 互斥锁 同时只允许一个线程更改数据,而Semaphore是同时允许一定数量的线程更改数据
  • 比如厕所有3个坑,那最多只允许3个人上厕所,后面的人只能等里面有人出来了才能再进去
  • 如果指定信号量为3,那么来一个人获得一把锁,计数加1,当计数等于3时,后面的人均需要等待。
  • 一旦释放,就有人可以获得一把锁

信号量与进程池的概念很像,但是要区分开,信号量涉及到加锁的概念

from multiprocessing import Process, Semaphore
import time
import random


def run(sem, i):
    sem.acquire()
    print(f'用户{i}占了一个信号位!')
    time.sleep(random.randint(0, 3))
    sem.release()
    print(f'用户{i}释放了一个信号位!')


def main():
    sem = Semaphore(2)

    p_list = []

    for i in range(6):
        p = Process(target=run, args=(sem, i))
        p.start()
        p_list.append(p)

    for p in p_list:
        p.join()


if __name__ == '__main__':
    main()


# 在没有进程结束并释放的时候只允许最多2个进程同时运行
"""
用户0占了一个信号位!
用户2占了一个信号位!
用户2释放了一个信号位!
用户1占了一个信号位!
用户0释放了一个信号位!
用户3占了一个信号位!
用户3释放了一个信号位!
用户4占了一个信号位!
用户4释放了一个信号位!
用户1释放了一个信号位!
用户5占了一个信号位!
用户5释放了一个信号位!
"""

二、事件

[1]关于事件

  • Event(同线程一样)

[2]事件的处理方法

  • python线程的事件用于主线程控制其他线程的执行,事件主要提供了三个方法 set、wait、clear。
  • 事件处理的机制:
    • 全局定义了一个“Flag”
    • 如果“Flag”值为 False,那么当程序执行 event.wait 方法时就会阻塞
    • 如果“Flag”值为True,那么event.wait 方法时便不再阻塞。
    • clear:
      • 将“Flag”设置为False
    • set:
      • 将“Flag”设置为True
from multiprocessing import Process, Event
import time
import random


def car(event, n):
    # 车辆到达红绿灯的时间是随机的
    time.sleep(random.randint(1, 10))
    # 如果到达的时候是红灯
    if not event.is_set():
        # 红灯的时候就等着
        print(f'\033[31m红灯亮了\033[0m,车{n}等着')
        # 等到变成绿的就走了
        event.wait()
        print(f'\033[32m绿灯亮了\033[0m,车{n}走了')
    # 如果来的时候就是绿灯就直接走
    else:
        print(f'\033[32m绿灯亮了\033[0m,车{n}走了')


def traffic_lights(event, interval):
    # 默认是红灯(False)
    while True:
        # 红绿灯时间都是五秒
        time.sleep(interval)
        # 五秒秒后如果是红灯就变绿灯
        if event.is_set():
            event.clear()
        # 如果是绿灯就变红灯
        else:
            event.set()


if __name__ == '__main__':
    # 设置事件(默认值是False)红灯
    e = Event()
    # 一共十辆车
    for i in range(10):
        p = Process(target=car, args=(e, i,))
        p.start()
    # 设置红绿灯,变化时间为五秒
    t = Process(target=traffic_lights, args=(e, 5))
    t.start()

"""
============》
红灯亮了,车6等着
红灯亮了,车2等着
红灯亮了,车5等着
红灯亮了,车9等着
红灯亮了,车0等着
红灯亮了,车1等着
红灯亮了,车8等着
红灯亮了,车4等着
绿灯亮了,车6走了!
绿灯亮了,车2走了!
绿灯亮了,车5走了!
绿灯亮了,车9走了!
绿灯亮了,车0走了!
绿灯亮了,车8走了!
绿灯亮了,车4走了!
绿灯亮了,车1走了!
红灯亮了,车3等着
绿灯亮了,车3走了!
红灯亮了,车7等着
绿灯亮了,车7走了!
"""
posted @ 2024-04-09 20:36  桃源氏  阅读(47)  评论(0)    收藏  举报