欢迎访问宙启技术站
智能推送

Python中的wait()函数:了解如何处理线程的阻塞和唤醒

发布时间:2024-01-02 15:37:20

在Python中,可以使用线程的wait()函数来实现线程的阻塞和唤醒操作。wait()函数用于使当前线程进入等待状态,并释放所占有的锁。当其他线程调用相同锁对象的notify()或notifyAll()函数时,被阻塞的线程会被唤醒并重新获得锁,从而继续执行。

下面是一个使用wait()函数进行线程的阻塞和唤醒的例子:

import threading

# 定义一个共享资源,表示当前打印到的数字
number = 1

# 创建一个控制线程的锁对象
lock = threading.Lock()

# 打印奇数的线程
def print_odd():
    global number, lock
    while number <= 10:
        # 加锁
        lock.acquire()
        if number % 2 != 0:
            print("奇数线程:", number)
            number += 1
        # 释放锁,并进入等待状态
        lock.wait()
        # 解锁
        lock.release()

# 打印偶数的线程
def print_even():
    global number, lock
    while number <= 10:
        # 加锁
        lock.acquire()
        if number % 2 == 0:
            print("偶数线程:", number)
            number += 1
        # 唤醒其他正在等待的线程
        lock.notify()
        # 释放锁
        lock.release()

# 创建奇数线程和偶数线程
odd_thread = threading.Thread(target=print_odd)
even_thread = threading.Thread(target=print_even)

# 启动线程
odd_thread.start()
even_thread.start()

# 等待线程结束
odd_thread.join()
even_thread.join()

在上面的例子中,我们首先定义了一个共享资源number,表示当前打印到的数字。然后创建了一个控制线程的锁对象lock。接下来定义了两个线程函数print_odd()和print_even(),分别用于打印奇数和偶数。

在print_odd()函数中,首先通过acquire()函数获取锁对象,然后判断当前的number是否为奇数,如果是奇数则打印并将number加1。接着调用wait()函数释放锁对象,并进入等待状态,直到被其他线程调用notify()函数唤醒。最后释放锁对象。

在print_even()函数中,与print_odd()函数类似,不同的是判断的是number是否为偶数,打印的是偶数。在打印完成后,调用的是notify()函数去唤醒其他正在等待的线程。

最后,我们创建了奇数线程和偶数线程,并分别启动它们。通过调用join()函数,我们等待两个线程全部结束。

当上述代码运行时,我们会发现输出结果是交替打印的奇数和偶数,即奇数线程和偶数线程交替执行。这是因为在奇数线程中,当打印完一个奇数后,它会调用wait()函数释放锁,并进入等待状态。此时偶数线程获取到了锁,并打印了一个偶数后,调用notify()函数唤醒了奇数线程,使其继续执行。同理,在偶数线程中,当打印完一个偶数后,它会调用wait()函数释放锁,并进入等待状态,此时奇数线程获取到了锁,打印了一个奇数后调用notify()函数唤醒了偶数线程。

通过上述例子,我们可以看到在Python中使用wait()函数可以很方便地实现线程的阻塞和唤醒操作,并充分利用锁对象的等待和唤醒机制来实现线程间的同步。