1. 程式人生 > >多程序,協程

多程序,協程

多程序

並行,同時執行。 一個程式執行起來之後,程式碼用到的資源稱之為程序,它是作業系統分配資源的基本單位,不僅可以通過執行緒完成多工,程序也是可以的

程序之間是相互獨立的

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