一、創建行程的兩種方式
#第一種 from multiprocessing import Process import time def task(n): print('我是子行程') time.sleep(n) print('子行程結束') if __name__ == '__main__': # args=(), kwargs={} # t=Process(task,args=(1,)) t = Process(target=task, kwargs={'n': 1}) t.start() # 通知作業系統,開啟行程,執行task函式 print('主') #第二種: from multiprocessing import Process import time class Task(Process): def __init__(self, n): super().__init__() self.n = n def run(self): print('我是子行程') time.sleep(self.n) print('子行程結束') if __name__ == '__main__': t = Task(1) # t.run(1) # 不是呼叫t.run(),而是呼叫t.start() t.start() print('主')
二、行程間資料相互隔離
#行程之間資料隔離 from multiprocessing import Process import time age = 18 def task(n): global age # 區域修改全域 age = 99 print('我是子行程') time.sleep(n) print('子行程結束') print(age) if __name__ == '__main__': t = Process(target=task, kwargs={'n': 1}) t.start() t.join() # 等待t子行程執行完成 print('主') print(age) # 資料沒有變,主行程中列印age和子行程的age沒有半毛錢關系,資料是隔離的
三、行程調度
1 先來先服務(對長作業有利,對短作業無益)
2 短作業優先(對短作業有利,對長作業無益)
3 時間片輪轉
4 多級反饋佇列
四、僵尸行程與孤兒行程
1 僵尸行程:行程結束了,資源還沒來得及回收
2 孤兒行程:主行程掛了,子行程還沒結束,它就會被專門的行程接管
五、行程物件及其他方法
1 windows:tasklist |findstr 行程id號
2 mac,Linux:ps aux | grep 行程id號
3 行程物件:t=Process(target=task, )或者是在行程內部:current_process()
4 t.pid或者current_process().pid 獲取行程id號
5 os.getpid() 同上,獲取行程id號
6 os.getppid() 獲取父行程id號,子行程中獲取父行程id,等于父行程的id號
7 t.is_alive()或者current_process().is_alive() 查看行程是否存活
8 t.terminate() 關閉行程,在主行程關閉
from multiprocessing import Process,current_process import time import os # 每個行程都會有自己的id號pid def task(): print('子行程') # 當前行程的id號 print(current_process().pid) print(os.getpid()) # 跟上面列印出來是一模一樣的 # 取出該行程父id號 print('-----',os.getppid()) # current_process()當前行程物件 print(current_process().is_alive()) time.sleep(2) print('子行程結束') if __name__ == '__main__': t = Process(target=task, ) t.start() # t1 = Process(target=task, ) # t1.start() # t.is_alive() # t這個行程是否存活 # print('主行程列印的結果',t.is_alive()) print(t.pid) time.sleep(0.5) # t.terminate() # 把t行程關閉 # time.sleep(0.1) print('主行程列印的結果', t.is_alive())
六、守護行程
from multiprocessing import Process, current_process import time import os def task(): # print(os.getpid()) print('子行程') time.sleep(200) print('子行程結束') if __name__ == '__main__': t = Process(target=task, ) # 守護行程:主行程一旦結束,子行程也結束 # t.daemon=True # 一定要加在啟動之前 t.start() time.sleep(1) print('主行程結束') print(os.getppid()) time.sleep(100) # 問題1 :主行程的父行程是誰? 答案:就是pycharm # 問題2 :主行程開了很多子行程,每個都需要設定守護嗎? 答案:看你的需求,你想讓某個行程是守護:t.daemon=True
七、互斥鎖
同時只有一個人能拿到,必須釋放,其他人才能再次獲取到
from multiprocessing import Process, Lock import json import time import random def search(): # 查票的函式 # 打開檔案,讀出ticket_count with open('ticket', 'r', encoding='utf-8') as f: dic = json.load(f) print('余票還有:', dic.get('ticket_count')) def buy(): with open('ticket', 'r', encoding='utf-8') as f: dic = json.load(f) time.sleep(random.randint(1, 3)) # 模擬一下網路延遲 if dic.get('ticket_count') > 0: # 能夠買票 dic['ticket_count'] -= 1 # 保存到檔案中去 with open('ticket', 'w', encoding='utf-8') as f: json.dump(dic, f) print('買票成功') else: # 買票失敗 print('買票失敗') # 寫一個函式,先查票,再買票 def task(mutex): search() # 買票程序要加鎖 # 買前加鎖 # mutex.acquire() # buy() # 10個行程變成了串行執行 # # 買后釋放鎖 # mutex.release() with mutex: buy() if __name__ == '__main__': # 鎖的創建,在哪?主行程創建鎖 mutex = Lock() # 創建一把鎖 # 模擬十個人買票(開10個行程) for i in range(10): t = Process(target=task, args=(mutex,)) t.start() # 面向物件高級:魔法方法(__開頭的),__enter__和__exit__,背景關系管理器 # 自己寫一個類,實作類似于打開檔案 with open 的功能 # with MyClass('檔案名','方式','編碼') as f: # f.read() #在這寫代碼,f就關閉了
接上面問題 補充:
魔法方法之:__inter__ __exit__
class MyClass(): def __init__(self,file_name,mode,encoding): self.file_name=file_name self.mode=mode self.encoding=encoding def __enter__(self): print('只要有with,就會執行我') self.file=open(self.file_name,self.mode,encoding=self.encoding) return self.file def __exit__(self, exc_type, exc_val, exc_tb): # 只要頂格寫代碼,就會執行我 print('只要頂格寫代碼,就會執行我') self.file.close() with MyClass('ticket','r','utf-8') as f: print(f.read()) print('xxss') print("sdfadasf") # a=MyClass('ticket','r','utf-8')#這樣做不會列印__enter__里的內容
八、佇列介紹
from multiprocessing import Queue # 實體化得到要給物件 q=Queue(5) # 默認很大,可以放很多,寫了個5,只能放5個 # 往管道中放值 q.put(1) q.put('lqz') q.put(18) q.put(19) # q.put(20) # q.put(21) # q.put_nowait(100) # 從管道中取值 # print(q.get()) # print(q.get()) # print(q.get()) # print(q.get(timeout=100)) # 等0.1s還沒有值,就結束 # print(q.get_nowait()) # 不等了,有就是有,沒有就沒有 print(q.empty()) # 看一下佇列是不是空的 print(q.full()) # 看一下佇列是不是滿的
q=Queue(佇列大小)
# 放值
q.put(asdf)
q.put_nowait(asdf) # 佇列滿了,放不進去就不放了,報錯
# 取值
q.get() # 從佇列頭部取出一個值
q.get_nowait() # 從佇列頭部取值,沒有就拋錯
# 佇列是否為空,是否滿
print(q.empty()) # 看一下佇列是不是空的
print(q.full()) # 看一下佇列是不是滿的
九、IPC機制(行程間通信)
Inter-Process Communication,行程間通信
from multiprocessing import Process, current_process, Queue import time import os def task1(q): print('我是task1行程,我的id號是:%s'%os.getpid()) q.put('lqz is handsome') def task2(q): # res=q.get() # print('我是task2行程,我的id號是:%s'%os.getpid(),res) print('我是task2行程,我的id號是:%s'%os.getpid()) if __name__ == '__main__': q = Queue(5) t1 = Process(target=task1, args=(q,)) t1.start() t2 = Process(target=task2, args=(q,)) t2.start() print(q.get())
---37---
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/30888.html
標籤:Python
上一篇:C++問題
下一篇:面試
