# base_data--->{"ticket_num": 1} # 模擬搶票軟件 import json import time from multiprocessing import Process # 查看餘票 def search(user): with open('base_data', 'r', encoding='utf-8') as f: dic = json.load(f) ticket_num = dic.get('ticket_num') print(f'用戶{user}正在查看餘票, 當前餘票{ticket_num}張...') # 購買車票 def buy(user): with open('base_data', 'r', encoding='utf-8') as f: dic = json.load(f) # 阻塞 time.sleep(1) if dic.get('ticket_num') > 0: dic['ticket_num'] -= 1 with open('base_data', 'w', encoding='utf-8') as f1: json.dump(dic, f1) print(f'用戶[{user}]搶票成功!') else: print(f'用戶[{user}]搶票失敗!') # 開始搶票 def run(user): search(user) buy(user) if __name__ == '__main__': for i in range(10): # 併發開啓10個子進程 p = Process(target=run, args=(f'{i}',)) p.start() ''' 用戶8正在查看餘票, 當前餘票1張... 用戶6正在查看餘票, 當前餘票1張... 用戶3正在查看餘票, 當前餘票1張... 用戶0正在查看餘票, 當前餘票1張... 用戶4正在查看餘票, 當前餘票1張... 用戶2正在查看餘票, 當前餘票1張... 用戶1正在查看餘票, 當前餘票1張... 用戶7正在查看餘票, 當前餘票1張... 用戶5正在查看餘票, 當前餘票1張... 用戶9正在查看餘票, 當前餘票1張... 用戶[8]搶票成功! 用戶[6]搶票成功! 用戶[3]搶票成功! 用戶[4]搶票成功! 用戶[1]搶票成功! 用戶[5]搶票成功! 用戶[2]搶票成功! 用戶[0]搶票成功! 用戶[7]搶票成功! 用戶[9]搶票成功! '''
使用進程鎖將併發變成串行json
# 模擬搶票軟件 import json import time from multiprocessing import Process from multiprocessing import Lock # 查看餘票 def search(user): with open('base_data', 'r', encoding='utf-8') as f: dic = json.load(f) ticket_num = dic.get('ticket_num') print(f'用戶[{user}]正在查看餘票, 當前餘票{ticket_num}張...') # 購買車票 def buy(user): with open('base_data', 'r', encoding='utf-8') as f: dic = json.load(f) time.sleep(1) if dic.get('ticket_num') > 0: dic['ticket_num'] -= 1 with open('base_data', 'w', encoding='utf-8') as f1: json.dump(dic, f1) print(f'用戶[{user}]搶票成功!') else: print(f'用戶[{user}]搶票失敗!') # 開始搶票 def run(user, mutex): # 上鎖 mutex.acquire() search(user) buy(user) # 解鎖 mutex.release() if __name__ == '__main__': # 調用Lock()類獲得一個鎖對象 mutex = Lock() for i in range(10): # 併發開啓10個子進程 p = Process(target=run, args=(f'{i}', mutex)) p.start() ''' 用戶[0]正在查看餘票, 當前餘票1張... 用戶[0]搶票成功! 用戶[3]正在查看餘票, 當前餘票0張... 用戶[3]搶票失敗! 用戶[2]正在查看餘票, 當前餘票0張... 用戶[2]搶票失敗! 用戶[4]正在查看餘票, 當前餘票0張... 用戶[4]搶票失敗! 用戶[8]正在查看餘票, 當前餘票0張... 用戶[8]搶票失敗! 用戶[6]正在查看餘票, 當前餘票0張... 用戶[6]搶票失敗! 用戶[7]正在查看餘票, 當前餘票0張... 用戶[7]搶票失敗! 用戶[5]正在查看餘票, 當前餘票0張... 用戶[5]搶票失敗! 用戶[1]正在查看餘票, 當前餘票0張... 用戶[1]搶票失敗! 用戶[9]正在查看餘票, 當前餘票0張... 用戶[9]搶票失敗! '''
from multiprocessing import Queue q = Queue(5) # 隊列中最多存放5個數據 # 填入數據 q.put('數據1') q.put('數據2') q.put('數據3') q.put('數據4') q.put('數據5') # q.put('數據6') # 數據填滿了繼續存放, 程序會被卡住 # 查看隊列是否填滿 print(q.full()) # 隊列滿了, 則會會報錯 # q.put_nowait('數據6') # 獲取數據, 若隊列中無數據可獲取, 程序會卡住 print(q.get()) print(q.get()) print(q.get()) print(q.get()) print(q.get()) # 隊列中沒有, 則會報錯 # print(q.get_nowait()) # 判斷隊列是否爲空 print(q.empty()) ''' True 數據1 數據2 數據3 數據4 數據5 True '''
from multiprocessing import Process, Queue import time # 定義生產者 def producer(q): for i in range(5): data = f'包子{i}' q.put(data) print(f'生產了{data}') time.sleep(0.1) # 定義生產者 def consumer(q): while True: data = q.get() print(f'吃了{data}') if __name__ == '__main__': q = Queue() p1 = Process(target=producer, args=(q,)) p2 = Process(target=consumer, args=(q,)) p1.start() p2.start() print('主') ''' 主 生產了包子0 吃了包子0 生產了包子1 吃了包子1 生產了包子2 吃了包子2 生產了包子3 吃了包子3 生產了包子4 吃了包子4 '''
from threading import Thread import time # 方式一 def task(): print('線程開啓') time.sleep(1) print('線程結束') if __name__ == '__main__': t = Thread(target=task) t.start() # 方式二 class MyThread(Thread): def run(self): print('線程開啓') time.sleep(1) print('線程結束') if __name__ == '__main__': t = MyThread() t.start()
from threading import Thread, Lock import time n = 100 def task(i): print(f'線程{i}啓動...') global n temp = n time.sleep(0.1) n = temp - 1 print(n) if __name__ == '__main__': for i in range(10): t = Thread(target=task, args=(i + 1,)) t.start() ''' 線程1啓動... 線程2啓動... 線程3啓動... 線程4啓動... 線程5啓動... 線程6啓動... 線程7啓動... 線程8啓動... 線程9啓動... 線程10啓動... 99 99 99 99 99 99 99 99 99 99 '''
from threading import Thread, Lock import time mutex = Lock() n = 100 def task(i): mutex.acquire() print(f'線程{i}啓動...') global n temp = n time.sleep(0.1) n = temp - 1 print(n) mutex.release() if __name__ == '__main__': for i in range(10): t = Thread(target=task, args=(i + 1,)) t.start() ''' 線程1啓動... 99 線程2啓動... 98 線程3啓動... 97 線程4啓動... 96 線程5啓動... 95 線程6啓動... 94 線程7啓動... 93 線程8啓動... 92 線程9啓動... 91 線程10啓動... 90 '''