學習**
分類目錄——多程序
是multiprocessing模組下的乙個類,是一種建立多程序的更加簡便的方式,可以更加方便的分配任務與傳遞引數。
pool = mp.pool(processes=6)
生成程序池
pool的兩個任務分配的函式
.map(函式名,引數列表的列表)
所謂的引數列表的列表是把所有的任務的引數列表再封裝到乙個列表中,形成乙個二維列表。這樣pool就會根據把列表中的引數分配給自己所擁有的(pool(池)中的)所有程序來執行。
multi_res =
(i,)
)for i in
range(10
)]print
([res.get(
)for res in multi_res]
)
這個例子在***整個程式的說明中也有體現。
什麼事是迭代器?
我的個人理解就是每用到結果才會去進行獲得該結果的操作,像是一種即用即算,是一種省空間的機制
我乍一看到這種方式有種感覺是它會消耗更多的時間,於是我在job中做了time.sleep(1)
的延遲,用來做耗時測試。
上程式跑一下
# mp.pool() 可以獲得return的值
import multiprocessing as mp
import time
defjob
(x):
time.sleep(1)
return x*x
defmulticore()
: pool = mp.pool(processes=6)
# 建立多個程序,程序數有引數porcesses指定
# 如不指定預設processes是機器的全部核心數(虛擬核)
# pool通過 .map() 分配多工
st = time.time(
) res = pool.
map(job,
range(10
))# map(job, job引數列表的列表)會用pool呼叫多執行緒來完成所有這些工作
print
(res)
et = time.time(
)print
('time:'
, et-st)
st = time.time()(
2,))
# 這種只能傳乙個值(也就是乙個job的引數)
print
(res.get())
et = time.time(
)print
('time:'
, et - st)
# 迭代器:每用到結果才會去進行獲得該結果的操作,像是一種即用即算,是一種省空間的機制
st = time.time(
) multi_res =
(i,)
)for i in
range(10
)]print
([res.get(
)for res in multi_res]
) et = time.time(
)print
('time:'
, et - st)
if __name__ ==
'__main__'
: multicore(
)
output:[0
,1,4
,9,16
,25,36
,49,64
,81]time:
2.1289286613464355
4time:
1.0010693073272705[0
,1,4
,9,16
,25,36
,49,64
,81]time:
2.0023622512817383
結果表明並沒有更耗時間,反而好像比.map()的方式快了一丟丟。
此外我還做了一項測試,當我把pool = mp.pool(processes=6)
中的process去掉時,即根據我的機器核心數生成程序數時,我的機器能虛擬出12個核,那這個pool應該就生成了12個執行緒,結果時間縮短了一半,程式中給pool分配了10套引數,也就是安排了10個任務。6個程序來做,要做兩波;12個程序來做,一波就完成了,這麼分析的話,也是合理的。
這是乙個典型的4核cpu,
在多執行緒中,通過global可以定義乙個全域性的變數來供多個執行緒間共享,但是這在多程序中是行不通的,下面就來說一下multiprocessing中設定的共享記憶體機制。
設定共享的單個值value = mp.value('d', 1)
獲得共享的單個值value.value
共享列表array = mp.array('i', [1, 2, 3])
注:mp下的array只能是一維的列表獲得共享的列表
array[:]
注:直接print(array)出來的是乙個物件,可以按索引取值 array[1],取全部就是 array[:]multiprocessing會把設定的共享變數放置在共享記憶體中,以供多個程序,呼叫共享變數。下面用程式來說明
import multiprocessing as mp
defjob
(v, n)
: v.value +=
1 n +=
1if __name__ ==
'__main__'
: value = mp.value(
'd',1)
num =
10print
('before p, value='
, value.value,
', num='
, num)
p1 = mp.process(target=job, args=
(value, num)
) p1.start(
) p1.join(
)print
('after p1, value='
, value.value,
', num='
, num)
p2 = mp.process(target=job, args=
(value, num)
) p2.start(
) p2.join(
)print
('after p2, value='
, value.value,
', num='
, num)
output:
before p, value=
1.0, num=
10after p1, value=
2.0, num=
10after p2, value=
3.0, num=
10
可以看到,設定在mp共享記憶體的變數可以在多程序見進行值傳遞,普通變數則不可以。
共享就存在著資料安全的問題,應該避免同時寫的問題,這是可以用加鎖的方式處理的,這裡為了簡單,只談共享,我在程序start()之後進行了.join(),即在當前程序結束之後才可以建立下乙個程序。
在mp下,可以設定為共享的就只有.value()和.array(),實際上其他資料型別也是可以共享的,這些資料型別的共享在multiprocessing.manager下,使用方式可參見 python多程序程式設計-程序間共享資料(value、array、manager)
python多程序之程序池
在利用python進行系統管理的時候,特別是同時操作多個檔案目錄,或者遠端控制多台主機,並行操作可以節約大量的時間。當被操作物件數目不大時,可以直接利用multiprocessing中的process動態成生多個程序,十幾個還好,但如果是上百個,上千個目標,手動的去限制程序數量卻又太過繁瑣,此時可以...
python 多程序 高階 程序池
如果需要啟動大量的子程序,使用程序池批量建立子程序的方式更加常見,因為當被操作對物件數目不大時,可以直接利用multiprocessing中的process動態生成多個程序,如果數量大,此時就應該使用pool。pool 可以提供指定數量的程序供使用者呼叫,預設大小是cpu的核數。當有新的請求提交到p...
Python多程序 程序池pool
from multiprocessing import process,pool import time defselect time.sleep 1 print time.ctime return 這是每個進行執行完後返回的值,該值會會被 callback函式接收 def foo args pri...