使用一个例子探析:生产者消费者在多线程之间的通信的使用

133 阅读2分钟

项目需求

有三个模块函数我们有如下特性:

  1. fun1模块函数启动的时候后续的两个模块才跟着启动;
  2. fun2模块函数会生成3个返回值;
  3. fun3模块函数将使用fun2模块函数产生的值处理。

  现需要将如上的三个函数模块进行如下操作,fun2与fun3是处于Ture循环中,fun2一直负责生产数据而fun3则是一直进行消费数据

需求分析

  对于上述的三个函数模块我们能很好的构造出来,构造函数文件名为Fun:

import random

def fun1():
    print("启动")

def fun2():
    x = random.random()
    a = x + 1
    b = x + 2
    c = x + 3
    return a, b, c

def fun3(a, b, c):
    y = a + b + c
    print(y)

  这三个函数模块我们单独构建好了,剩下的就是如何构建Tur循环进行生产者消费者模式的搭建了,通过上面的Fun.py中我们能够看出fun1是作为启动函数,可以建立在生产者消费者的前面。剩下的就是如何将函数fun2和fun3使用生产者消费者搭建起来。

  明显可以看出:fun2是作为生产者(运行一次可以得到a,b,c三个值),fun3是作为消费者(消费fun2生产的三个值进行处理),这里可以我们选择队列进行完成函数值的传递。

from queue import Queue

queue = Queue()  # 实例化队列

参考代码

from threading import Thread
import time
from queue import Queue
import Fun


class Producer(Thread):
    def __init__(self,queue):
        super(Producer, self).__init__()

        self.queue = queue

    def run(self):
        while True:
            x1, x2, x3 = Fun.fun2()

            self.queue.put(x1)
            self.queue.put(x2)
            self.queue.put(x3)
            time.sleep(1)


class Consumer(Thread):
    def __init__(self,queue):
        super(Consumer, self).__init__()
        self.queue = queue

    def run(self):
        while True:
            try:
                Fun.fun3(self.queue.get_nowait(), self.queue.get_nowait(), self.queue.get_nowait())
                print("队列长度", self.queue.qsize())
            except Exception:
                print('消费者出错')
            # time.sleep(random.randrange(2))
            time.sleep(1)


if __name__ == '__main__':
    print("---主线程开始---")
    Fun.fun1()
    queue = Queue()  # 实例化队列
    producer = Producer(queue)  # 实例化线程 Producer,并传入队列作为参数
    consumer = Consumer(queue)  # 实例化线程 Consumer,并传入队列作为参数
    producer.start()  # 启动线程 Producer
    consumer.start()  # 启动线程 Consumer
    producer.join()  # 等待线程 Producer 结束
    consumer.join()  # 等待线程 Consumer 结束
    print("---主线程结束---")