并发编程之Event事件

Event事件

事件处理的方法:

event.is_set():返回event的状态值;
event.wait():如果 event.isSet()==False将阻塞线程;
event.set(): 设置event的状态值为True,所有阻塞池的线程激活进入就绪状态, 等待操作系统调度;
event.clear():恢复event的状态值为False。

事件处理的机制:

首先,全局定义了一个“Flag”
   1. 如果“Flag”值为 False,那么当程序执行 event.wait 方法时就会阻塞
   2. 如果“Flag”值为True,那么event.wait 方法时便不再阻塞。
clear方法:
   - 将“Flag”设置为False
set方法:
   - 将“Flag”设置为True

代码示例:

from threading import Thread, Event
import time

event = Event()


def student(user):
    print(f'{user}  正在上课')
    event.wait(2)  # 阻塞2s
    print(f'{user}  正在上体育课')


def teacher(user):
    print(f'{user}  正在讲课中')
    time.sleep(5)  # 阻塞5s
    print(f'{user}  说下课了')
    event.set()


if __name__ == '__main__':
    stu1 = Thread(target=student, args=('xiao',))
    stu2 = Thread(target=student, args=('quan',))
    stu3 = Thread(target=student, args=('zheng',))
    teacher = Thread(target=teacher, args=('zhao',))
    stu1.start()
    stu2.start()
    stu3.start()
    teacher.start()

# xiao  正在上课
# quan  正在上课
# zheng  正在上课
# zhao  正在讲课中
# quan  正在上体育课
# zheng  正在上体育课
# xiao  正在上体育课
# zhao  说下课了

MySQL案例:

##  例如,有多个工作线程尝试链接MySQL,我们想要在链接前确保MySQL服务正常才让那些工作线程去连接MySQL服务器,如果连接不成功,都会去尝试重新连接。那么我们就可以采用threading.Event机制来协调各个工作线程的连接操作

from threading import Thread, Event
import threading
import time, random


def conn_mysql():
    count = 1
    while not event.is_set():
        if count > 3:
            raise TimeoutError('链接超时')
        print('<%s>第%s次尝试链接' % (threading.current_thread().name, count))
        event.wait(0.5)
        count += 1
    print('<%s>链接成功' % threading.current_thread().name)


def check_mysql():
    print('\033[45m[%s]正在检查mysql\033[0m' % threading.current_thread().name)
    time.sleep(random.randint(2, 4))
    event.set()


if __name__ == '__main__':
    event = Event()
    conn1 = Thread(target=conn_mysql)
    conn2 = Thread(target=conn_mysql)
    check = Thread(target=check_mysql)

    conn1.start()
    conn2.start()
    check.start()
import time
from threading import Thread, Event, current_thread

event = Event()


def conn():
    n = 0
    while not event.is_set():
        if n == 3:
            print('%s try too many times' % current_thread().name)
            return
        print('%s try %s' % (current_thread().name, n))
        event.wait(0.5)
        n += 1

    print('%s is connected' % current_thread().name)


def check():
    print('%s is checking' % current_thread().name)
    time.sleep(5)
    event.set()


if __name__ == '__main__':
    for i in range(3):
        t = Thread(target=conn)
        t.start()
    t = Thread(target=check)
    t.start()

# Thread-1 (conn) try 0
# Thread-2 (conn) try 0
# Thread-3 (conn) try 0
# Thread-4 (check) is checking
# Thread-3 (conn) try 1
# Thread-1 (conn) try 1
# Thread-2 (conn) try 1
# Thread-2 (conn) try 2
# Thread-3 (conn) try 2
# Thread-1 (conn) try 2
# Thread-1 (conn) try too many times
# Thread-2 (conn) try too many times
# Thread-3 (conn) try too many times
posted @ 2024-01-21 21:58  Xiao0101  阅读(52)  评论(0)    收藏  举报