Python是運行在解釋器中的語言,查找資料知道,python中有一個全局鎖(GIL),在使用多線程(Thread)的情況下,不能發揮多核的優勢。而使用多進程(Multiprocess),則可以發揮多核的優勢真正地提高效率。
單核cpu執行多任務的原理:操作系統交替輪流地執行各個任務。先讓任務1執行0.01秒,然后切換到任務2執行0.01秒,再切換到任務3執行0.01秒...這樣往復地執行下去。由于cpu的執行速度非常快,所以使用者的主觀感受就是這些任務在并行地執行。
多核cpu執行多任務的原理:由于實際應用中,任務的數量往往遠超過cpu的核數,所以操作系統實際上是把這些多任務輪流地調度到每個核心上執行。
Python多進程編程
1. multiprocessing
multiprocessing是Python提供的一個跨平臺的多進程模塊,通過它可以很方便地編寫多進程程序,在不同的平臺(Unix/Linux, Windows)都可以執行。如:
2. Pool?
某些情況下,我們希望批量創建多個子進程,或者給定子進程數的上限,避免無限地消耗系統的資源。通過Pool(進程池)的方式,就可以完成這項工作,下面是使用Pool的代碼:
close()方法和terminate()方法的區別:
close:關閉進程池,使之不能再添加新的進程。已經執行的進程會等待繼續執行直到結束。
terminate:強制終止線程池,正在執行的進程也會被強制終止。
3. 進程間通信?
Python的multiprocessing模塊提供了多種進程間通信的方式,如Queue、Pipe等。
3.1 Queue、Lock
Queue是multiprocessing提供的一個模塊,它的數據結構就是"FIFO——first in first out"的隊列,常用的方法有:put(object)入隊;get()出隊;empty()判斷隊列是否為空。
Lock:當多個子進程對同一個queue執行寫操作時,為了避免并發操作產生沖突,可以通過加鎖的方式使得某個子進程對queue擁有唯一的寫權限,其他子進程必須等待該鎖釋放后才能再開始執行寫操作。
下面就是使用Queue進行進程間通信的代碼:在父進程里創建兩個子進程,分別實現對queue的讀和寫操作.
#!/usr/bin/python
# -*- coding: utf-8 -*
import? sys
reload (sys)
sys.setdefaultencoding('utf-8')
from multiprocessing import Process, Queue, Lock
import os, time, random
#寫數據進程
def write(q, lock, name):
? ? print 'Child Process %s starts' % name
? ? #獲得鎖
? ? lock.acquire()
? ? for value in ['A' , 'B', 'C']:
? ? ? ? print 'Put %s to queue...' % value
? ? ? ? q.put(value)
? ? ? ? time.sleep(random.random())
? ? #釋放鎖
? ? lock.release()
? ? print 'Child Process %s ends' % name
#讀數據進程
def read(q, lock, name):
? ? print 'Child Process %s starts' % name
? ? while True: #持續地讀取q中的數據
? ? ? ? value =q.get()
? ? ? ? print 'Get %s from queue.' % value
? ? print 'Child Process %s ends' % name
if __name__ == "__main__":
? ? #父進程創建queue,并共享給各個子進程
? ? q= Queue()
? ? #創建鎖
? ? lock = Lock()
? ? #創建第一個“寫”子進程
? ? pw = Process(target = write , args=(q, lock, 'WRITE', ))
? ? #創建“讀”進程
? ? pr = Process(target = read, args=(q,lock, 'READ',))
? ? #啟動子進程pw,寫入:
? ? pw.start()
? ? #啟動子進程pr,讀取:
? ? pr.start()
? ? #等待pw結束:
? ? pw.join()
? ? #pr是個死循環,通過terminate殺死:
? ? pr.terminate()
? ? print 'Test finish.'
3.2 Pipe
Pipe是另一種進程間通信的方式,俗稱“管道”。它由兩端組成,一端往管道里寫入數據,另一端從管道里讀取數據。
下面就是使用Pipe通信的代碼:
python多線程threading模塊
多線程加鎖例子:
python遞歸鎖RLock