Operating System OS, Python - Producer Consumer Model

1. Buffer (used here as a blocking queue) to solve the problem of strong coupling between consumers and producers. (Producer and consumer do not communicate directly)

2. Improve the overall data processing speed of the program by balancing producer threads and consumer threads.

3. This pattern can solve most concurrency problems in concurrent programming.

Example 1. Producer produces once and each consumer consumes once

import threading
import queue
import time
 
def producer():
    for i in range(10):
        q.put("饺子 %s" % i )
 
    print("开始等待所有的饺子被取走...")
    q.join()
    print("所有的饺子被取完了...")
    
 
def consumer(n):
 
    while q.qsize() >0:
        print("%s 取到" %n  , q.get())
        q.task_done() 
        time.sleep(1)
 
q = queue.Queue()
 
 
 
p1 = threading.Thread(target=producer,)
p1.start()
 
p2 = threading.Thread(target=consumer, args=('Allen1',))
p2.start()

p3 = threading.Thread(target=consumer, args=('Allen2',))
p3.start()

Example 2. Producers and consumers dynamically generate or consume

Knowledge points:

  1. Critical section (lock and unlock)
  2. Buffer (blocking queue in this case)
  3. Producer, consumer synchronization
import time,random
import queue,threading

#缓冲区用阻塞队列实现
q = queue.Queue()
#临界区指的是一个访问共用资源(例如:共用设备或是共用存储器)的程序片段,而这些共用资源又无法同时被多个线程访问的特性
#生成全局锁,对缓冲区这个共享资源(临界资源)进行加锁解锁操作
lock = threading.Lock()

def Producer(name):
    """
        生产者在0-3秒内动态生产饺子
    """
    count = 1
    global lock

    while True:
        time.sleep(random.randrange(3))
        #生产者线程进入临界区
        #修改缓冲区前加锁
        lock.acquire()
        #缓冲区满,生产者线程阻塞,虽然此处的缓冲区(队列)没有设置maxsize
        q.put(count, block=True)
        print('Producer %s produced 1 jiaozi, has produced %s jiaozi...%i jiaozi left' %(name, count, q.qsize()))
        count +=1
        lock.release()
        #生产者线程退出临界区

def Consumer(name):
    """
        消费者在0-4秒内动态消费饺子
    """
    count = 1
    global lock

    while True:
        time.sleep(random.randrange(4))
        #消费者线程进入临界区
        lock.acquire()
        
        if not q.empty():
            #缓冲区为空,消费者线程阻塞,虽然此处的缓冲区(队列)没有设置maxsize
            q.get(block=True)           
           
            print('\033[32;1mConsumer %s took 1 jiaozi, has taken %s jiaozi...%i jiaozi left\033[0m' %(name, count, q.qsize()))
            count += 1
        lock.release()
        #消费者线程退出临界区 

if __name__ == '__main__':        
    p1 = threading.Thread(target=Producer, args=('p1',))
    p2 = threading.Thread(target=Producer, args=('p2',))
    c1 = threading.Thread(target=Consumer, args=('c1',))
    c2 = threading.Thread(target=Consumer, args=('c2',))
    p1.start()
    p2.start()
    c1.start()
    c2.start()

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324730719&siteId=291194637