標籤:family name 任務 nts python模組 ast 文法 ide htm
上節回顧:
線程 vs 進程
https://www.cnblogs.com/alex3714/articles/5230609.html
threading.get_ident()擷取線程號
線程:作業系統調度的最小單位;進程是一簇線程的集合,本身不能操作,進程至少包含一個線程;
線程同時修改同一份資料時必須加鎖,mutex互斥鎖。
遞迴鎖。
join()是結束上一個線程,讓下一個進程能夠執行。等待上一個線程執行完畢。
守護線程(slave):服務於非守護線程(master),
queue(隊列):1、解耦,使程式直接首先松耦合;2、提高處理效率;
queue.Queue() FIFO=first in first out
queue.LifoQueue() LIFO=last in first out
PriorityQueue(maxsize=0) 優先順序隊列。
python中的多線程是偽多線程,其實是CPU的環境切換,本質是單線程。
io 操作不佔用CPU,比如從網上讀取;
計算佔用CPU,如1+1佔用CPU;
Python的多線程,不適合CPU密集操作型的任務,適合io密集型的任務。
Python的進程也是使用作業系統的原生進程。進程之間是相互獨立的。進程之間的資料是獨立的,不能共用,進程也能解決作業系統多核的使用。
進程在python模組是multiprocessing,下面來產生一個進程執行個體:
import multiprocessingimport timedef f(name): time.sleep(2) print(‘hello‘, name)if __name__ == ‘__main__‘: p = multiprocessing.Process(target=f, args=(‘bob‘,)) #產生一個線程執行個體 p.start() p.join()
上面代碼產生了一個進程,可以看出,進程與線程的文法幾乎一樣。
啟用多個進程:
import multiprocessingimport timedef f(name): time.sleep(1) print(‘hello‘, name)if __name__ == ‘__main__‘: for i in range(10): p = multiprocessing.Process(target=f, args=(‘bob‘,)) #產生一個線程執行個體 p.start() # p.join()
運行結果如下:
hello bobhello bobhello bobhello bobhello bobhello bobhello bobhello bobhello bobhello bob
每一個進程都是由父進程啟動的。
from multiprocessing import Processimport osdef info(title): print(title) print(‘module name:‘, __name__) print(‘parent process:‘, os.getppid()) #父進程的ID,每一個進程都是由父進程啟動的 print(‘process id:‘, os.getpid()) #子進程ID print("\n\n")def f(name): info(‘\033[31;1mcalled from child process function f\033[0m‘) print(‘hello‘, name)if __name__ == ‘__main__‘: info(‘\033[32;1mmain process line\033[0m‘) p = Process(target=f, args=(‘bob‘,)) p.start() p.join()
從上面代碼可以看出,任何一個進程都是有父進程啟動的。Linux裡面有一個超級父進程。
進程間通訊
不同進程間記憶體是不共用的,要想實現兩個進程間的資料交換,可以用以下方法:
Queues
使用方法跟threading裡的queue差不多
兩個進程之間的記憶體是獨立的。q=queue.Queue()是線程queue,from multiprocessing import Queue是進程Queue。
from multiprocessing import Process, Queueimport osdef func(): print("線程名字:",__name__) print("父線程:",os.getppid()) print("當前進程:",os.getpid())def f(q): q.put([42, None, ‘hello‘])if __name__ == ‘__main__‘: q = Queue() #進程queue func() p = Process(target=f, args=(q,)) #子進程的,是不能訪問父進程的記憶體的 p.start() print(q.get()) # prints "[42, None, ‘hello‘]" p.join()
運行結果如下:
線程名字: __main__
父線程: 2561
當前進程: 32596
[42, None, ‘hello‘]
進程Queue是兩個Queue,不是共用Queue,是通過pickle進行轉換,複製一份,讓進程看起來實現了相互連信。
day10--非同步IO\資料庫\隊列\緩衝