多程序,協程
阿新 • • 發佈:2018-11-27
多程序
並行,同時執行。 一個程式執行起來之後,程式碼用到的資源稱之為程序,它是作業系統分配資源的基本單位,不僅可以通過執行緒完成多工,程序也是可以的
程序之間是相互獨立的
cpu計算密集的時候適合用多程序
有幾核CPU就可以同時執行幾個程序
開啟程序需要呼叫 multiprocessing 模組
import multiprocessing #呼叫程序模組 import time def test1(): for i in range(5): time.sleep(1) print('test', i) def test2(): for i in range(5): time.sleep(1) print('test', i) if __name__ == '__main__': #固定格式(必須加)後面的執行程式碼要縮排 p1 = multiprocessing.Process(target=test1) #新增一個test1變成一個子程序賦值給p1 p2 = multiprocessing.Process(target=test2) p1.start() #開啟p1子程序 p2.start()
結果:
#停頓一秒 test 0 test 0 #停頓一秒 test 1 test 1 #停頓一秒 test 2 test 2 #停頓一秒 test 3 test 3 #停頓一秒 test 4 test 4
程序之間不共享,相互獨立
import multiprocessing g_num = 0 def edit(): global g_num for i in range(10): g_num += 1 print(g_num) def reader(): print(' ') print(g_num) if __name__ == '__main__': p1 = multiprocessing.Process(target=edit) p2 = multiprocessing.Process(target=reader()) p1.start() p2.start() print(g_num)
結果:
全域性變數沒有被改變
0
0
10
程序池的併發
apply_async 是非同步非阻塞的。即不用等待當前程序執行完畢,隨時根據系統排程來進行程序切換。首先主程序開始執行,碰到子程序後,主程序仍可以先執行,等到作業系統進行程序切換的時候,在交給子程序執行。可以做到不等待子程序執行完畢,主程序就已經執行完畢,並退出程式。
import multiprocessing #呼叫程序模組 from multiprocessing import Pool #呼叫程序池模組 import time import threading g_num= 0 def test1(): for i in range(10): time.sleep(1) print('test1', i) def test2(): for i in range(10): time.sleep(1) print('test2', i) def test3(): for i in range(10): time.sleep(1) print('test3', i) if __name__ == '__main__': pool = Pool() #括號裡寫幾就代表可以允許同時執行幾個程序,不寫的話就按照cpu的各項指標系統分配同時執行的程序數。 pool.apply_async(test1) ##維持執行的程序,當一個程序執行完畢後會新增新的程序進去 pool.apply_async(test2) pool.apply_async(test3) pool.close() #關閉程序池,表示不能再往程序池中新增程序,需要在join之前呼叫 pool.join() #等待程序池中的所有程序執行完畢
程序包括執行緒(執行緒是輕量級的)
執行緒包括協程(協程是微量級的)
協程比執行緒更加適合IO密集的操作
協程
協程,又稱微執行緒,纖程。英文名Coroutine。 首先我們得知道協程是啥?協程其實可以認為是比執行緒更小的執行單元。 為啥說他是一個執行單元,因為他自帶CPU上下文。這樣只要在合適的時機, 我們可以把一個協程 切換到另一個協程。 只要這個過程中儲存或恢復 CPU上下文那麼程式還是可以執行的。
那麼這個過程看起來和執行緒差不多。其實不然, 執行緒切換從系統層面遠不止儲存和恢復 CPU上下文這麼簡單。 作業系統為了程式執行的高效性每個執行緒都有自己快取Cache等等資料,作業系統還會幫你做這些資料的恢復操作。 所以執行緒的切換非常耗效能。但是協程的切換隻是單純的操作CPU的上下文,所以一秒鐘切換個上百萬次系統都抗的住。
需要呼叫 gevent 模組,第三方模組,需要pip下載。
import gevent,time from gevent import monkey monkey.patch_all() def test1(): for i in range(10): time.sleep(1) print('1===>', i) def test2(): for i in range(10): time.sleep(2) print('2===>', i) g1 = gevent.spawn(test1) g2 = gevent.spawn(test2) g1.join() g2.join()
因為第一個協程挺一秒,第二個協程停2秒,所以CPU一個時間段內執行兩次協程1,一次協程2
1===> 0 2===> 0 1===> 1 1===> 2 2===> 1 1===> 3 1===> 4 2===> 2 2===> 3 2===> 4