python程序设计:多线程与多进程编程

本文介绍了一种使用Python实现的多生产者、多消费者及多缓冲区的同步问题解决方案,通过队列、线程和事件控制,确保了生产者生产速度大于消费者消费速度的场景下,系统的稳定运行。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、题目要求

用python编写程序实现多个生产者,多个消费者和多个缓冲区的同步问题,并且生产者的生产速度大于消费者的消费速度

2、不专业讲解

  • 这里的缓存区其实就是使用了多个队列,生产者即往队列放入数据,消费者则删除队列的数据。
  • 生产者类class Producer(threading.Thread)和消费者类class Consumer(threading.Thread)的定义表明,Producer和Consumer都继承自 threading.Thread,即可以使用多线程方法。
  • 在创建线程的时候,会自动执行__init__()初始化方法, 当我们执行线程的start()方法会执行run()方法。join()方法会堵塞主线程,等待线程执行完毕后才放行。
  • threading.Event()是threading提供的机制类似于一个线程向其它多个线程发号施令的模式,Event为False,会堵塞线程(执行clear()方法),Event为True,会开放线程(执行set()方法)。

3、代码

#!/usr/bin/python

import queue
import random
import threading


# 定义最大线程数常量
THREAD_MAX_NUM = 5
# 定义每个队列长度常量
QUEUE_MAX_SIZE = 10
# 定义缓冲区数量常量
BUFFER_MAX = 3
# 定义全局缓存区
queue_list = []


# 生产者
class Producer(threading.Thread):
    def __init__(self, name, thread_event, num, buffer_index):
        threading.Thread.__init__(self)
        self.name = "生产者" + str(name)
        self.queue = queue_list[buffer_index]
        self.event = thread_event
        self.num = num
        self.str_index = " 在缓存区" + str(buffer_index)
        self.count = 0

    def run(self):
        while self.count < self.num:
            # 判断栈是否已经满
            if self.queue.full():
                # 栈满 线程进入等待
                self.event.wait()
                # 线程唤醒后将flag设置为False
                if self.event.isSet():
                    self.event.clear()
            else:
                self.event.set()
                # 向栈添加数据
                data = random.randint(0, 5000)
                self.queue.put(data)
                print(self.name + self.str_index + " 生产数据 " + str(data) + '\n')

            self.count += 1


# 消费者
class Consumer(threading.Thread):
    def __init__(self, name, thread_event, thread_lock, num, buffer_index):
        threading.Thread.__init__(self)
        self.name = "消费者" + str(name)
        self.queue = queue_list[buffer_index]
        self.event = thread_event
        self.lock = thread_lock
        self.num = num
        self.str_index = " 在缓存区" + str(buffer_index)
        self.count = 0

    def run(self):
        while self.count < self.num:
            # 判断栈是否为空
            if self.queue.empty():
                # 栈空 线程进入等待
                self.event.wait()
                # 线程唤醒后将flag设置为False
                if self.event.isSet():
                    self.event.clear()
            else:
                self.event.set()
                # 向栈消耗数据
                self.lock.acquire()
                data = self.queue.get()
                self.queue.task_done()
                self.lock.release()
                print(self.name + self.str_index + " 消费数据 " + str(data) + '\n')

            self.count += 1


if __name__ == '__main__':
    # 创建缓冲区
    for i in range(BUFFER_MAX):
        queue_list.append(queue.Queue(maxsize=QUEUE_MAX_SIZE))

    event = threading.Event()
    lock = threading.Lock()
    threads = []
    # 创建线程
    for i in range(THREAD_MAX_NUM):
    	# 生成不大于缓冲区数量的的随机数字(随机在某个缓冲区生产或消费数据)
        index = random.randint(0, len(queue_list) - 1)
        # 创建 生产者和消费者 线程
        threads.append(Producer(i, event, QUEUE_MAX_SIZE, index))
        threads.append(Consumer(i, event, lock, QUEUE_MAX_SIZE, index))

    # 开始所有线程
    for t in threads:
        t.start()

    # 等待所有线程完成
    for t in threads:
        t.join()

     # 查看缓存区情况
    for i in range(BUFFER_MAX):
        print("缓存区 %s 还有 %s 条数据" % (i, queue_list[i].qsize()))
        while not queue_list[i].empty():
            print(queue_list[i].get())

4、程序运行结果示例

生产者0 在缓存区2 生产数据 4636
生产者0 在缓存区2 生产数据 1640
生产者0 在缓存区2 生产数据 3452
生产者0 在缓存区2 生产数据 898
消费者0 在缓存区2 消费数据 4636
生产者0 在缓存区2 生产数据 663
消费者0 在缓存区2 消费数据 1640
消费者0 在缓存区2 消费数据 3452
消费者0 在缓存区2 消费数据 898
消费者0 在缓存区2 消费数据 663
生产者1 在缓存区1 生产数据 3609
生产者1 在缓存区1 生产数据 1447
消费者1 在缓存区1 消费数据 3609
消费者1 在缓存区1 消费数据 1447
生产者2 在缓存区2 生产数据 1698
生产者2 在缓存区2 生产数据 2335
生产者2 在缓存区2 生产数据 3085
生产者2 在缓存区2 生产数据 1661
生产者2 在缓存区2 生产数据 507
消费者2 在缓存区2 消费数据 1698
消费者2 在缓存区2 消费数据 2335
消费者2 在缓存区2 消费数据 3085
消费者2 在缓存区2 消费数据 1661
消费者2 在缓存区2 消费数据 507
生产者1 在缓存区1 生产数据 4820
生产者1 在缓存区1 生产数据 834
生产者1 在缓存区1 生产数据 3730

缓存区 0 还有 0 条数据
缓存区 1 还有 3 条数据
4820
834
3730
缓存区 2 还有 0 条数据
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值