寫之前在猶豫,是否需要將多執行緒放在這個之前講或者將多執行緒和多程序合到一起講python的併發性,鑑於內容較多,還是分為兩個吧。
這次將介紹multiprocessing模組的用法、怎麼寫多程序程式、程序間通訊、程序間資料共享等。由於python使用了內部的gil,在任意時刻只允許單個執行緒執行,無論系統有多少個cpu,程式只能在乙個cpu上執行,這導致資源的極大浪費。所以多程序的出現可以很好的解決這個問題。說到程序,可能首先想到的是os和subprocess模組中建立子程序的函式,但是多程序和這個還是有區別的,在處理問題上有一定的區別。閒話少說,進入正題。
1、建立程序
#coding=utf-8
from multiprocessing import process
from time import sleep
def work(param):
while true:
print param
sleep(1)
if __name__ == '__main__':
param = 'test'
process = process(target=work, args=(param,), name= 'process1')
# process.daemon = true
process.start()
print process.pid
print process.name
sleep(1)
# process.join()
上述方法為比較常用的建立多程序的方法,也可以自己實現乙個類,繼承process類,並重寫run方法,同樣可以達到目的。
使用process時,target為要呼叫的函式名,args為函式需要的引數(乙個元組),name為程序名。
可以通過process物件拿到建立程序的程序名和id。
daemon=true表示建立的程序為後台程序,當主程序執行完後子程序也會退出,否則掛起等待子程序退出。
join函式表示此時主程序等待,直到子程序執行完畢。
2、程序池
在需要建立多個(成百上千)程序的時候,靠人工乙個個複製顯然行不通,multiprocessing模組提供了乙個執行緒池來解決這個問題。
這個跟c裡的佇列基本一樣,只是joinablequeue加入了task_done等屬性,管道的用法也類似,這裡就不介紹了。# encoding: utf-8
import multiprocessing,time
def func(msg):
for i in xrange(3):
print msg
time.sleep(1)
return "done " + msg
if __name__ == "__main__":
pool = multiprocessing.pool(processes=4)
result =
for i in xrange(10):
msg = "hello %d" %(i)
pool.close()
pool.join()
for res in result:
print res.get()
map:可以將被呼叫物件func應用給引數iterable中的每乙個項,並返回執行結果。如果不需要得到返回結果,這個函式是可以使用的,如果要返回結果,則用map_async函式。
map_async:跟map一樣,但是返回的結果是乙個asyncresult物件,可以稍後回去結果。
3、程序間通訊
multiprocessing模組支援程序間通訊有兩種形式:佇列和管道。都是使用訊息傳遞實現的。
# encoding: utf-8
import multiprocessing,time
def consumer(input_q):
while true:
item = input_q.get()
print item
#發訊號通知任務完成
input_q.task_done()
def producer(sequence,output_q):
for item in sequence:
output_q.put(item)
if __name__ == "__main__":
q = multiprocessing.joinablequeue()
cons_p = multiprocessing.process(target=consumer, args=(q,))
cons_p.daemon = true
cons_p.start()
sequence = [1,2,34,5,]
producer(sequence,q)
q.join()
4、共享記憶體資料
def worker(num, mystr, arr):
num.value *= 2
mystr.value = str(os.getpid())
for i in range(len(arr)):
arr[i] = arr[i] * -1 + 1.5
def dump_vars(num, mystr, arr):
print 'num: ', num.value
print 'str: ', mystr[:]
print 'arr: ', arr[:]
def test_sharedmemory():
num = value('i', 5)
mystr = array('c', 'just for test')
arr = array('d', [1.0, 1.5, -2.0])
print 'init value'
dump_vars(num, mystr, arr)
ps = [process(target=worker, args=(num, mystr, arr)) for _ in range(3)]
for p in ps:
p.start()
for p in ps:
p.join()
print
print 'after all workers finished'
dump_vars(num, mystr, arr)
if __name__=='__main__':
test_sharedmemory()
這部分自己平時沒怎麼用過,上述**是從別的地方copy過來的,留個記錄,以後要用的時候可以再參考下。
5、總結
上述的幾個都比較淺顯,還有一些東西給略過了如manager。今天的這些東西看了一下午,頭都大了,寫到後面的兩節時快沒心思,以後得克服。
Python學習筆記(四)
dict 用 dict 表示 名字 成績 的查詢表如下 d 名字稱為key,對應的成績稱為value,dict就是通過 key 來查詢 value。key不能重複 花括號 表示這是乙個dict,然後按照 key value,寫出來即可。最後乙個 key value 的逗號可以省略。由於dict也是集...
python學習筆記(四)
0.假設你現在拿到了乙個英語句子,需要把這個句子中的每乙個單詞拿出來單獨處理。sentence i am an englist sentence 這時就需要對字串進行分割。sentence.split split 會把字串按照其中的空格進行分割,分割後的每一段都是乙個新的字串,最終返回這些字串組成乙...
python學習筆記 四
python模組,乙個.py檔案 匯入模組的語法 import importable importable 可以是包或包中的模組 import importable1,importablen import importable as preferred name 第三種語法可能導致名稱衝突 一般寫在...