一個Python多執行緒例項
阿新 • • 發佈:2018-12-09
水果分配的問題:
桌上有一隻盤子,每次只能放入5只水果。爸爸專放蘋果,
媽媽專放橘子,一個兒子專等吃盤子中的橘子,一個女兒專等吃盤子中的蘋果.用P,V操作實現爸爸、媽媽、兒子、女兒程序的同步控制。
貼一下程式碼:
import random import threading import time #建立訊號量threading.Semaphore(value),value是訊號量的初始值。 # acquire() 訊號量-1,當為0時,阻塞當前執行緒。release() 訊號量+1,大於0,喚醒等待此訊號量的一個執行緒。 empty =threading.Semaphore(5) # 盤子的容量 apple =threading.Semaphore(0) # 同步蘋果的訊號量 orange =threading.Semaphore(0) # 同步橘子的訊號量 mutex = threading.Event() # 表示四個程序互斥的訪問盤子 plate = list() # 模擬水果盤 lock = threading.Lock() # plate互斥鎖 mutex.set() # 設定為True def father(basket): global empty, mutex, lock, apple while len(basket) != 0: # 當蘋果籃子中沒有蘋果,則終止 # 1.p(empty) empty.acquire() # 將容量empty減去1 # 2.p(mutex) mutex.clear() # mutex設定為False 其它執行緒將等待 # 3.put apple if lock.acquire(): temp = basket.pop() plate.append(temp) # 從蘋果籃子裡拿出一個蘋果放入水果盤 print('->father put anapple({0}) into plate.'.format(temp)) print(' current plate = ', plate) lock.release() # 4.v(mutex) mutex.set() # mutex設定為True, 其它執行緒可以使用 # 5.v(apple) apple.release() #time.sleep() #執行緒推遲指定的時間執行,單位為秒 #random.random() #用於生成一個0到1的隨機符點數: 0 <= n < 1.0 time.sleep(random.random()) def mother(basket): global empty, mutex, lock, orange while len(basket) != 0: # 當橘子籃子中沒有橘子,則終止 # 1.p(empty) empty.acquire() # 將容量empty減去1 # 2.p(mutex) mutex.clear() # mutex設定為False 其它執行緒將等待 # 3.put(orange) if lock.acquire(): temp = basket.pop() plate.append(temp) print('->mother put anorange({0}) into plate.'.format(temp)) print(' current plate = ', plate) lock.release() # 4.v(mutex) mutex.set() # mutex設定為True, 其它執行緒可以使用 # 5.v(orange) orange.release() time.sleep(random.random()) def son(count): global empty, mutex, lock, orange for i in range(count): # 1.p(orange) orange.acquire() # orange -1 # 2.p(mutex) mutex.clear() # mutex設定為False 其它執行緒將等待 # 3.get orange if lock.acquire(): for fruit in plate: if fruit.startswith('Orange'): temp = fruit plate.remove(fruit) break print('->son take an orange({0})from plate.'.format(temp)) print(' current plate = ', plate) lock.release() # 4.v(mutex) mutex.set() # mutex設定為True, 其它執行緒可以使用 # 5.v(empty) empty.release() # 將empty + 1 time.sleep(random.random()) def daughter(count): global empty, mutex, lock, apple for i in range(count): # 1.p(apple) apple.acquire() # apple -1 # 2.p(mutex) mutex.clear() # mutex設定為False 其它執行緒將等待 # 3.get apple if lock.acquire(): for fruit in plate: if fruit.startswith('Apple'): temp = fruit plate.remove(fruit) break print('->daughter take anapple({0}) from plate'.format(temp)) print(' current plate = ', plate) lock.release() # 4.v(mutex) mutex.set() # mutex設定為True, 其它執行緒可以使用 # 5.v(empty) empty.release() # 將empty + 1 time.sleep(random.random()) if __name__ == '__main__': # 初始化蘋果和橘子的個數 apples_basket = ['Apple-A', 'Apple-B','Apple-C', "Apple-D"] # 模擬蘋果籃子,一共有4個蘋果要放入水果盤 oranges_basket = ['Orange-A', 'Orange-B','Orange-C'] # 模擬橘子籃子,一共有3個橘子要放入水果盤 # 建立4個執行緒 #建立執行緒threading.Thread(target, args), target是要執行的函式,args是函式所需的引數。 father = threading.Thread(name='Father',target=father, args=(apples_basket, )) #father 執行緒 mother = threading.Thread(name='Mother',target=mother, args=(oranges_basket, )) # mother 執行緒 son = threading.Thread(name='Son',target=son, args=(len(oranges_basket), )) # son 執行緒 daughter =threading.Thread(name='Daughter', target=daughter, args=(len(apples_basket),)) # daughter 執行緒 # 啟動執行緒 daughter.start() son.start() father.start() mother.start()
執行結果: