執行緒是最小的執行單元,而程序由至少乙個執行緒組成。如何排程程序和執行緒,完全由作業系統決定,程式自己不能決定什麼時候執行,執行多長時間。
在 python 中我們要同時執行多個任務怎麼辦?
有兩種解決方案:
由於 python 是跨平台的,自然也應該提供乙個跨平台的多程序支援。multiprocessing 模組就是跨平台版本的多程序模組。
multiprocessing 模組提供了乙個 process 類來代表乙個程序物件,下面的例子演示了啟動乙個子程序並等待其結束:
from multiprocessing import process
import os
# 子程序要執行的**
defrun_proc
(name)
:print
('run child process %s (%s)...'
%(name, os.getpid())
)if __name__==
'__main__'
:print
('parent process %s.'
% os.getpid())
p = process(target=run_proc, args=
('test',)
)print
('child process will start.'
) p.start(
) p.join(
)print
('child process end.'
)
建立子程序時,只需要傳入乙個執行函式和函式的引數,建立乙個process例項,用start()方法啟動,這樣建立程序比fork()還要簡單。
join()方法可以等待子程序結束後再繼續往下執行,通常用於程序間的同步。
結果如下:
parent process 928.
child process will start.
run child process test (929)...
process end.
如果要啟動大量的子程序,可以用程序池的方式批量建立子程序:
from multiprocessing import pool
import os, time, random
deflong_time_task
(name)
:print
('run task %s (%s)...'
%(name, os.getpid())
) start = time.time(
) time.sleep(random.random()*
3)end = time.time(
)print
('task %s runs %0.2f seconds.'
%(name,
(end - start)))
if __name__==
'__main__'
:print
('parent process %s.'
% os.getpid())
p = pool(4)
for i in
range(5
):(i,)
)print
('waiting for all subprocesses done...'
) p.close(
) p.join(
)print
('all subprocesses done.'
)
**解讀:
對pool物件呼叫join()方法會等待所有子程序執行完畢,呼叫join()之前必須先呼叫close(),呼叫close()之後就不能繼續新增新的process了。
請注意輸出的結果,task 0,1,2,3是立刻執行的,而task 4要等待前面某個task完成後才執行,這是因為pool的預設大小在我的電腦上是4,因此,最多同時執行4個程序。
結果:
parent process 669.
waiting for all subprocesses done...
run task 0 (671)...
run task 1 (672)...
run task 2 (673)...
run task 3 (674)...
task 2 runs 0.14 seconds.
run task 4 (673)...
task 1 runs 0.27 seconds.
task 3 runs 0.86 seconds.
task 0 runs 1.41 seconds.
task 4 runs 1.91 seconds.
all subprocesses done.
很多時候,子程序並不是自身,而是乙個外部程序。我們建立了子程序後,還需要控制子程序的輸入和輸出。
subprocess 模組可以讓我們非常方便地啟動乙個子程序,然後控制其輸入和輸出。
import subprocess
print
('$ nslookup www.python.org'
)r = subprocess.call(
['nslookup'
,'www.python.org'])
print
('exit code:'
, r)
輸出結果:
$ nslookup www.python.org
server: 192.168.19.4
address: 192.168.19.4#53
non-authoritative answer:
www.python.org canonical name = python.map.fastly.net.
name: python.map.fastly.net
address: 199.27.79.223
exit code: 0
process 之間肯定是需要通訊的,作業系統提供了很多機制來實現程序間的通訊。python 的 multiprocessing 模組包裝了底層的機制,提供了 queue、pipes 等多種方式來交換資料。
from multiprocessing import process, queue
import os, time, random
# 寫資料程序執行的**:
defwrite
(q):
print
('process to write: %s'
% os.getpid())
for value in
['a'
,'b'
,'c']:
print
('put %s to queue...'
% value)
q.put(value)
time.sleep(random.random())
# 讀資料程序執行的**:
defread
(q):
print
('process to read: %s'
% os.getpid())
while
true
: value = q.get(
true
)print
('get %s from queue.'
% value)
if __name__==
'__main__'
:# 父程序建立queue,並傳給各個子程序:
q = queue(
) pw = process(target=write, args=
(q,)
) pr = process(target=read, args=
(q,)
)# 啟動子程序pw,寫入:
pw.start(
)# 啟動子程序pr,讀取:
pr.start(
)# 等待pw結束:
pw.join(
)# pr程序裡是死迴圈,無法等待其結束,只能強行終止:
pr.terminate(
)
結果:
process to write: 50563
put a to queue...
process to read: 50564
get a from queue.
put b to queue...
get b from queue.
put c to queue...
get c from queue.
python之程序池
初始化pool時,可以指定 個最 程序數,當有新的請求提交到pool中時,如果池還沒有滿,那麼就會建立 個新的程序 來執 該請求 但如果池中 的程序數已經達到指定的最 值,那麼該請求就會等待,直到池中有程序結 束,才會建立新的程序來執行 3表示 程序池中對多有3個程序一起執行 pool pool 3...
Linux學習之程序
程序process pid 子程序 ppid 父程序 top 動態檢視系統程序占用資源高,不常用 ps aus 靜態檢視當前系統程序,常用。sort cpu 以cpu使用率來排序,降序 sort cpu 以cpu使用率來排序,公升序 sort mem 以記憶體占用情況來排序,降序。vsz rss t...
python 多程序學習
講解看 吧 把例子記一下 1.用fork建立程序 import osprint process s start.os.getpid pid os.fork if pid 0 print i am child process s and my parent is s os.getpid os.getp...