操作系統OS,Python - 生產者消費者模型
阿新 • • 發佈:2018-04-24
UC lease 整體 left 多個 eas 資源 解決 臨界區
1. 緩沖區(此處用阻塞隊列充當),解決消費者和生產者強耦合問題。(生產者和消費者不直接通信)
2. 通過平衡生產者線程和消費者線程,來提高程序整體處理數據速度。
3. 在並發編程中該模式能解決大多數並發問題。
例子1. 生產者生產一次,每個消費者消費一次
import threading
import queue
import time
def producer():
for i in range(10):
q.put("餃子 %s" % i )
print("開始等待所有的餃子被取走...")
#把操作隊列的線程join到生產者線程,待這些線程結束後,生產者線程再往下執行。
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()
例子2. 生產者和消費者動態生成或者消費
知識點:
- 臨界區(加鎖解鎖)
- 緩沖區(本例為阻塞隊列)
- 生產者,消費者同步
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()
操作系統OS,Python - 生產者消費者模型