Python多程序之multiprocessing模組和程序池的實現
1、利用multiprocessing可以在主程序中建立子程序,提升效率,下面是multiprocessing建立程序的簡單例子,和多執行緒的使用非常相似?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
'''
程式碼是由主程序裡面的主執行緒從上到下執行的,
我們在主執行緒裡面又建立了兩個子程序,子進
程裡面也是子執行緒在幹活,這個子程序在主進
程裡面
'''
import multiprocessing
import
time
def
f0(a1):
time.sleep(
3
)
print
(a1)
if
__name__
=
=
'__main__'
:
#windows下必須加這句
t
=
multiprocessing.Process(target
=
f0,args
=
(
12
,))
t.daemon
=
True
#將daemon設定為True,則主執行緒不比等待子程序,主執行緒結束則所有結束
t.start()
t2
=
multiprocessing.Process(target
=
f0, args
=
(
13
,))
t2.daemon
=
True
t2.start()
print
(
'end'
)
#預設情況下等待所有子程序結束,主程序才結束
|
這裡的結果是直接打印出end就結束了,因為添加了t.daemon=True,join方法在程序裡面也可以用,跟執行緒的用法非常相似
2、程序之間預設是不能共用記憶體的
?1 2 3 4 5 6 7 8 9 10 11 12 13 |
li
=
[]
def
f1(i):
li.append(i)
print
(
'你好'
,li)
if
__name__
=
=
'__main__'
:
#程序不能共用記憶體
for
i
in
range
(
10
):
p
=
Process(target
=
f1,args
=
(i,))
p.start()
'''每個程序都建立一個列表,然後新增一個因素進去,
每個程序之間的資料是不能共享的
|
結果如圖
如果將程式碼改成threading,由於執行緒共用記憶體,所以結果是不一樣的,執行緒操作列表li之前,拿到的是前一個執行緒操作過的li列表,如圖
3、如果要程序之間處理同一個資料,可以運用陣列以及程序裡面的manager方法,下面程式碼介紹的是manager方法
?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
from
multiprocessing
import
Process
from
multiprocessing
import
Manager
def
f1(i,dic):
dic[i]
=
200
+
i
print
(dic.values())
if
__name__
=
=
'__main__'
:
#程序間預設不能共用記憶體
manager
=
Manager()
dic
=
manager.
dict
()
#這是一個特殊的字典
for
i
in
range
(
10
):
p
=
Process(target
=
f1,args
=
(i,dic))
p.start()
p.join()
|
這裡輸出如圖,表示每個程序都是操作這個字典,最後的輸出是有10個元素
如果是普通的字典,輸出如圖
4、multiprocessing模組裡面的程序池Pool的使用
(1)apply模組的使用,每個任務是排隊執行的
?1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
from
multiprocessing
import
Process,Pool
from
multiprocessing
import
Manager
import
time
def
f1(a):
time.sleep(
2
)
print
(a)
if
__name__
=
=
'__main__'
:
pool
=
Pool(
5
)
for
i
in
range
(
5
):
#每次使用的時候會去程序池裡面申請一個程序
pool.
apply
(func
=
f1,args
=
(i,))
print
(
'你好'
)
#apply裡面是每個程序執行完畢了才執行下一個程序
pool.close()
#執行完close後不會有新的程序加入到pool,join函式等待所有子程序結束
pool.join()
#等待程序執行完畢,先呼叫close函式,否則會出錯
|
執行結果如圖
(2)apply_async模組,會比apply模組多個回撥函式,同時是非同步的
?1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
from
multiprocessing
import
Process,Pool
from
multiprocessing
import
Manager
import
time
def
Foo(i):
time.sleep(
1
)
return
i
+
50
def
Bar(arg):
print
(arg)
if
__name__
=
=
'__main__'
:
pool
=
Pool(
5
)
for
i
in
range
(
10
):
'''apply是去簡單的去執行,而apply_async是執行完畢之後可以執行一
個回撥函式,起提示作用'''
pool.apply_async(func
=
Foo,args
=
(i,),callback
=
Bar)
#是非同步的
print
(
'你好'
)
pool.close()
#不執行close會報錯,因為join的原始碼裡面有個斷言會檢驗是否執行了該方法
pool.join()
#等待所有子程序執行完畢,否則的話由於apply_async裡面daemon是設定為True的,主程序不會等子程序,所欲函式可能會來不及執行完畢就結束了
'''apply_async裡面,等函式Foo執行完畢,它的返回結果會被當做引數
傳給Bar'''
|
結果如圖
這兩個方法的主要區別如圖
1、利用multiprocessing可以在主程序中建立子程序,提升效率,下面是multiprocessing建立程序的簡單例子,和多執行緒的使用非常相似?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
'''
程式碼是由主程序裡面的主執行緒從上到下執行的,
我們在主執行緒裡面又建立了兩個子程序,子進
程裡面也是子執行緒在幹活,這個子程序在主進
程裡面
'''
import
multiprocessing
import
time
def
f0(a1):
time.sleep(
3
)
print
(a1)
if
__name__
=
=
'__main__'
:
#windows下必須加這句
t
=
multiprocessing.Process(target
=
f0,args
=
(
12
,))
t.daemon
=
True
#將daemon設定為True,則主執行緒不比等待子程序,主執行緒結束則所有結束
t.start()
t2
=
multiprocessing.Process(target
=
f0, args
=
(
13
,))
t2.daemon
=
True
t2.start()
print
(
'end'
)
#預設情況下等待所有子程序結束,主程序才結束
|
這裡的結果是直接打印出end就結束了,因為添加了t.daemon=True,join方法在程序裡面也可以用,跟執行緒的用法非常相似
2、程序之間預設是不能共用記憶體的
?1 2 3 4 5 6 7 8 9 10 11 12 13 |
li
=
[]
def
f1(i):
li.append(i)
print
(
'你好'
,li)
if
__name__
=
=
'__main__'
:
#程序不能共用記憶體
for
i
in
range
(
10
):
p
=
Process(target
=
f1,args
=
(i,))
p.start()
'''每個程序都建立一個列表,然後新增一個因素進去,
每個程序之間的資料是不能共享的
|
結果如圖
如果將程式碼改成threading,由於執行緒共用記憶體,所以結果是不一樣的,執行緒操作列表li之前,拿到的是前一個執行緒操作過的li列表,如圖
3、如果要程序之間處理同一個資料,可以運用陣列以及程序裡面的manager方法,下面程式碼介紹的是manager方法
?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
from
multiprocessing
import
Process
from
multiprocessing
import
Manager
def
f1(i,dic):
dic[i]
=
200
+
i
print
(dic.values())
if
__name__
=
=
'__main__'
:
#程序間預設不能共用記憶體
manager
=
Manager()
dic
=
manager.
dict
()
#這是一個特殊的字典
for
i
in
range
(
10
):
p
=
Process(target
=
f1,args
=
(i,dic))
p.start()
p.join()
|
這裡輸出如圖,表示每個程序都是操作這個字典,最後的輸出是有10個元素
如果是普通的字典,輸出如圖
4、multiprocessing模組裡面的程序池Pool的使用
(1)apply模組的使用,每個任務是排隊執行的
?1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
from
multiprocessing
import
Process,Pool
from
multiprocessing
import
Manager
import
time
def
f1(a):
time.sleep(
2
)
print
(a)
if
__name__
=
=
'__main__'
:
pool
=
Pool(
5
)
for
i
in
range
(
5
):
#每次使用的時候會去程序池裡面申請一個程序
pool.
apply
(func
=
f1,args
=
(i,))
print
(
'你好'
)
#apply裡面是每個程序執行完畢了才執行下一個程序
pool.close()
#執行完close後不會有新的程序加入到pool,join函式等待所有子程序結束
pool.join()
#等待程序執行完畢,先呼叫close函式,否則會出錯
|
執行結果如圖
(2)apply_async模組,會比apply模組多個回撥函式,同時是非同步的
?1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
from
multiprocessing
import
Process,Pool
from
multiprocessing
import
Manager
import
time
|