使用锁的方式创建一个生产者与消费者

一、关于生产者与消费者的理解

生产者与消费者

  • 1、生产者与消费者可以是多个(多线程),也可以是单个(单线程)
  • 2、生产者是生产、创造、产生东西、数据、任务
  • 3、消费者是消费生产者产出的东西
  • 4、生产者与消费者之间创建连接,是通过生产者生产的东西,放到一个全局变量(类似仓库的地方),消费者直接去里面获取消费
  • 5、简单点:生产者不停的往仓库放东西,消费者不停的从仓库拿走东西

二、定义一个生产者与消费者(生产包子与吃包子的案例)

  • 1、导包及定义线程锁

    import time
    import random
    import threading
    
    # 定义仓库里面多少包子
    gBum = 100
    # 创建一把锁
    gLock = threading.Lock()
    
  • 2、定义生产者类

    class Producer(threading.Thread):
        """
        定义一个生产者,来生产包子,在生产过程中上锁不销售
        """
    
        def run(self):
            global gBum
            while True:
                gLock.acquire()
                bum = random.randint(0, 10)
                gBum += bum
                gLock.release()
                print('{0}生产了:{1}个包子,还剩余:{2}个包子'.format(threading.current_thread(), bum, gBum))
                # 休眠时间,可以理解为生产包子需要时间
                time.sleep(random.randrange(3))
    
  • 3、定义消费者类

    class Consumer(threading.Thread):
        """
        定义一个消费者的类,来消费包子
        """
    
        def run(self):
            global gBum
            while True:
                bum = random.randint(0, 10)
                gLock.acquire()
                if gBum > bum:
                    gBum -= bum
                    print("{0}在消费包子,消费了{1}个,还剩余{2}".format(threading.current_thread(), bum, gBum))
                else:
                    print("{0}在消费包子,消费了{1}个,但是包子数量不够,还剩余{2}".format(threading.current_thread(), bum, gBum))
                gLock.release()
                # 休眠时间,可以理解为消费包子需要时间
                time.sleep(random.randrange(3))
    
  • 4、开启线程执行代码

    if __name__ == '__main__':
        # # 启动八个消费者线程
        for x in range(8):
            t = Consumer(name='消费者线程%d' % x)
            t.start()
    
        # 启动三个生产者
        for x in range(3):
            t = Producer(name='生产者%d' % x)
            t.start()
    
  • 5、打印信息(可以看到线程之间在不停的切换)

    <Producer(生产者2, started 123145628491776)>生产了:2个包子,还剩余:18个包子
    <Consumer(消费者线程0, started 123145575940096)>在消费包子,消费了4个,还剩余14
    <Consumer(消费者线程3, started 123145591705600)>在消费包子,消费了5个,还剩余9
    <Consumer(消费者线程4, started 123145596960768)>在消费包子,消费了0个,还剩余9
    <Consumer(消费者线程2, started 123145586450432)>在消费包子,消费了9个,但是包子数量不够,还剩余9
    <Consumer(消费者线程6, started 123145607471104)>在消费包子,消费了7个,还剩余2
    <Consumer(消费者线程6, started 123145607471104)>在消费包子,消费了10个,但是包子数量不够,还剩余2
    <Consumer(消费者线程1, started 123145581195264)>在消费包子,消费了10个,但是包子数量不够,还剩余2
    <Producer(生产者0, started 123145617981440)>生产了:9个包子,还剩余:11个包子
    <Producer(生产者0, started 123145617981440)>生产了:8个包子,还剩余:19个包子
    <Producer(生产者0, started 123145617981440)>生产了:2个包子,还剩余:21个包子
    <Producer(生产者0, started 123145617981440)>生产了:7个包子,还剩余:28个包子
    

三、添加条件来退出多线程

import time
import random
import threading

# 定义仓库里面多少包子
gBum = 100
# 总共生产多少次
gTotalTimes = 10
# 定义当前的
gTimes = 0
# 创建一把锁
gLock = threading.Lock()

class Producer(threading.Thread):
    """
    定义一个生产者,来生产包子,在生产过程中上锁不销售
    """

    def run(self):
        global gBum
        global gTotalTimes
        global gTimes
        while True:
            gLock.acquire()
            bum = random.randint(0, 10)
            # 当生产大于指定的次数的时候退出线程
            if gTimes >= gTotalTimes:
                gLock.release()
                break
            gBum += bum
            gTimes += 1
            gLock.release()
            print('{0}生产了:{1}个包子,还剩余:{2}个包子'.format(threading.current_thread(), bum, gBum))
            # 休眠时间,可以理解为生产包子需要时间
            time.sleep(random.randrange(3))

class Consumer(threading.Thread):
    """
    定义一个消费者的类,来消费包子
    """

    def run(self):
        global gBum
        global gTotalTimes
        global gTimes
        while True:
            bum = random.randint(0, 10)
            gLock.acquire()
            if gBum > bum:
                gBum -= bum
                print("{0}在消费包子,消费了{1}个,还剩余{2}".format(threading.current_thread(), bum, gBum))
            else:
                # 当包子不足的时候且当前数大于总共生产次数的时候退出线程
                if gTimes >= gTotalTimes:
                    print("{0}在消费包子,消费了{1}个,但是包子数量不够,还剩余{2}".format(threading.current_thread(), bum, gBum))
                    gLock.release()
                    break
            gLock.release()
            # 休眠时间,可以理解为消费包子需要时间
            time.sleep(random.randrange(3))

if __name__ == '__main__':
    # # 启动八个消费者线程
    for x in range(8):
        t = Consumer(name='消费者线程%d' % x)
        t.start()

    # 启动三个生产者
    for x in range(3):
        t = Producer(name='生产者%d' % x)
        t.start()

results matching ""

    No results matching ""