python之路--程序內容補充
阿新 • • 發佈:2019-01-09
1. 程序的其他方法
程序id, 程序名字, 檢視程序是否活著(is_alive()), terminate()傳送結束程序的訊號
import time import os from multiprocessing import Process def f1(): print('子程序的pid',os.getpid()) print('降龍十八掌天下第一') def f2(): print('六脈神劍舉世無雙') if __name__ == '__main__': p1 = Process(target=f1,name='我是程序1') p2 = Process(target=f2,) p1.start() p2.start() print(p1.name) # 我是程序1 print('子程序的pid',p1.pid) print('父程序的id',os.getpid()) def f1(): time.sleep(3) print('子程序1號') if __name__ == '__main__': p = Process(target=f1,) p.start() print(p.is_alive()) # True, 判斷程序是否活著 p.terminate() # 給系統傳送一個結束程序的訊號 time.sleep(0.5) # 為了讓避免併發導致的下面結果不準 print(p.is_alive()) # False
2. 殭屍程序和孤兒程序(瞭解)
殭屍程序可以理解為一些程序垃圾, 沒有實際作用, 但是在佔用著空間, 當這些程序的父程序正常關閉的時候會清楚這些殭屍程序,
孤兒程序也是一些程序垃圾, 只不過是當父程序非正常關閉的時候, 這些垃圾需要被最上級程序清理.
3. 驗證程序之間是空間隔離的
from multiprocessing import Process num = 100 def f1(): global num num = 3 print('子程序中的num',num) if __name__ == '__main__': p = Process(target=f1,) p.start() # 子程序中的num 3 p.join() print('主程序中的num',num) # 主程序中的num 100
4. 守護程序
import time from multiprocessing import Process def f1(): time.sleep(1) print('我是沉睡1秒的子程序') time.sleep(3) print('我是沉睡3秒子程序') # 打印不出來 def f2(): time.sleep(1) print('我是普通的子程序') if __name__ == '__main__': p = Process(target=f1,) # 將該程序設定為守護程序,必須寫在start之前, # 意思如果我的主程序程式碼執行結束了,你這個子程序不管執行到什麼地方,都直接結束 p.daemon = True p.start() # 開啟一個普通的子程序來驗證一下守護程序的結束只和主程序的程式碼執行結束有關係, # 而整個程式的結束需要主程序和普通的子程序的程式碼都執行結束才結束 p2 = Process(target=f2,) p2.start() time.sleep(2) print('====','我是主程序') # f1 只能打印出我是沉睡1秒的子程序, # 主程序打印出==== 我是主程序,然後打印出我是普通的子程序
5. 程序鎖(同步鎖/互斥鎖) (非常重要)
程序鎖就是為了保證資料安全, 比如說搶票如果只剩一張票的話,很多人同時訪問都能看到只剩一張票,如果不用程序鎖的資料就會發生錯誤.
import time from multiprocessing import Process,Lock def show_ticket(i): with open('ticket','r',encoding='utf-8') as f: ticket_data = f.read() # 檔案中的資料{'count': 1} t_data = eval(ticket_data) print('%s查詢剩餘票數為%s'%(i,t_data['count'])) def get_ticket(i,l1): # 上鎖,所有人只能搶這一個鎖,只有搶到了才能繼續執行,避免了由於併發導致的資料不準 l1.acquire() with open('ticket', 'r', encoding='utf-8') as f: ticket_data = f.read() # print(ticket_data) t_data = eval(ticket_data) if t_data['count'] > 0: t_data['count'] -= 1 print('%s搶票成功' % i) time.sleep(0.2) with open('ticket', 'w',) as f: f.write(str(t_data)) else: print('沒票了!!!') # 解鎖,解鎖之後才能重新搶鎖 l1.release() if __name__ == '__main__': l1 = Lock() for i in range(10): p1 = Process(target=show_ticket,args=(i,)) p1.start() for i in range(10): p2 = Process(target=get_ticket,args=(i,l1) ) p2.start() def f1(i,lic): with lic: # 直接完成了上鎖與解鎖的過程 time.sleep(1) print(i) if __name__ == '__main__': lic = Lock() for i in range(5): p = Process(target=f1, args=(i,lic)) p.start()
6. 佇列
from multiprocessing import Process,Queue q = Queue(3) q.put('喬峰') q.put('段譽') q.put('虛竹') print(q.get()) print(q.get()) print(q.get()) try: # 為了不等待直接執行下面的程式碼 如果是q.get()程式就會在這一直等著直到再次出現q.put() q.get_nowait() except: print('佇列拿空了') print('還有東西嗎?') # 基於佇列的通訊 def f1(q): q.put('約不約?') if __name__ == '__main__': q = Queue(3) p = Process(target=f1,args=(q,)) p.start() son_p_msg = q.get() print('來自子程序的訊息:', son_p_msg) # 來自子程序的訊息: 約不約?
7. 基於佇列的生產者消費者模型
import time from multiprocessing import Process,Queue,JoinableQueue def producer(q): for i in range(10): time.sleep(0.2) s = '大包子%s號' % i print('新鮮出爐' + s) q.put(s) # 這個q.join 是 JoinableQueue 裡面的join q.join() #就等著task_done()訊號的數量,和我put進去的數量相同時,才繼續執行 print('所有的任務都被處理了,繼續潛行吧騷年們') def consumer(q): while 1: time.sleep(0.5) baozi = q.get() print(baozi+'被吃了') q.task_done() #給佇列傳送一個取出的這個任務已經處理完畢的訊號 if __name__ == '__main__': q = JoinableQueue(30) #同樣是一個長度為30的佇列 pro_p = Process(target=producer,args=(q,)) con_p = Process(target=consumer,args=(q,)) pro_p.start() # 為了讓消費者吃完包子就走人 con_p.daemon = True con_p.start() # 這個join 是 process裡面的join pro_p.join() print('主程序結束') ### 這兩個join在兩個模組裡,功能不一樣
程序id,程序名字,檢視程序是否活著is_alive() terminate()傳送結束程序的訊號