1). unix/linux作業系統提供了乙個fork()系統呼叫,它非常特殊。普通的函式呼叫,
呼叫一次,返回一次,但是fork()呼叫一次,返回兩次,因為作業系統自動把當前程序(
稱為父程序)複製了乙份(稱為子程序),然後,分別在父程序和子程序內返回。
2). 子程序永遠返回0,而父程序返回子程序的id。這樣做的理由是,乙個父程序可以fork
出很多子程序,所以,父程序要記下每個子程序的id,而子程序只需要呼叫getppid()
就可以拿到父程序的id。
3). python的os模組封裝了常見的系統呼叫,其中就包括fork,可以在python程式中輕鬆
建立子程序:
原理: 父程序和子程序:, 如果父程序結束, 子程序也隨之結束;
先有父程序, 再有子程序. 類linux系統中(redhat,mac), fork函式;
常用函式:
os.fork()
os.getpid() # 獲取當前程序的pid (process id)
os.getppid() # 獲取當前程序的父程序pid (parent process id)
import os
print("當前程序(pid=%d)正在執行......." %(os.getpid()))
# 在pycharm編寫**, 程式的父程序就是pycharm;
print("當前程序的父程序為(pid=%d)正在執行....." %(os.getppid()))
print("開始建立子程序.....")
pid = os.fork()
print(pid)
if pid == 0:
print("這是子程序返回的是0, 子程序的pid為%d, 父程序為%d" %(os.getpid(), os.getppid()))
else:
print("這是父程序返回的,返回值為子程序的pid, 為%d" %(pid))
#---->輸出:
當前程序(pid=6557)正在執行.......
當前程序的父程序為(pid=4385)正在執行.....
開始建立子程序.....
6561
這是父程序返回的,返回值為子程序的pid, 為6561
0這是子程序返回的是0, 子程序的pid為6561, 父程序為6557
# 1.理解:
如果你打算編寫多程序的服務程式,unix/linux無疑是正確的選擇。由於windows
沒有fork呼叫,難道在windows上無法用python編寫多程序的程式?
由於python是跨平台的,自然也應該提供乙個跨平台的多程序支援。multiprocessing
模組就是跨平台版本的多程序模組。
multiprocessing模組提供了乙個process類來代表乙個程序物件,下面的例子演示了
啟動乙個子程序並等待其結束:
建立子程序時,只需要傳入乙個執行函式和函式的引數,建立乙個process例項,用start()方法啟動,這樣建立程序比fork()還要簡單。
join()方法可以等待子程序結束後再繼續往下執行,通常用於程序間的同步。
# 2. process使用屬性及方法
process 類用來描述乙個程序物件。建立子程序的時候,只需要傳入乙個執行函式和函式的引數即可完成 process 示例的建立。
start() 方法啟動程序,
join() 方法實現程序間的同步,等待所有程序退出。
close() 用來阻止多餘的程序湧入程序池 pool 造成程序阻塞。
multiprocessing.process(group=none, target=none, name=none, args=(), kwargs={}, *, daemon=none)
target 是函式名字,需要呼叫的函式
args 函式需要的引數,以 tuple 的形式傳入
# multiprocessing 跨平台實現多程序
import multiprocessing
def job():
print('當前程序:%s'%(multiprocessing.current_process()))
# 通過類的例項化實現
p1 = multiprocessing.process(target=job, name="我的第1個子程序")
p1.start()
p2 = multiprocessing.process(target=job, name="我的第2個子程序")
p2.start()
# join方法, 等待所有的子程序執行結束, 再執行主程序
p1.join()
p2.join()
print("任務執行結束.....")
# 類的方法實現多程序
import multiprocessing
class myprocess(multiprocessing.process):
# 重寫run方法*****start方法預設執行run方法
def run(self):
print("當前子程序的名稱%s....." % (multiprocessing.current_process()))
p1 = myprocess(name="first")
p1.start()
p2 = myprocess(name="second")
p2.start()
p1.join()
p2.join()
print("all finish.....")
# 多程序案例效率演示
import threading
import time
import functools
import multiprocessing
# 時間裝飾器
def timeit(f):
@functools.wraps(f)
start_time=time.time()
res=f(*args,**kwargs)
end_time=time.time()
print('%s函式執行的時間是%.2f' %(f.__name__,end_time-start_time))
return res
def job(li):
return sum(li)
@timeit
def no_use_thread():
li=range(1,100000000)
for i in range(5):
job(li)
@timeit
def use_thread():
li=range(1,100000000)
threads=
for i in range(5):
t=threading.thread(target=job,args=(li,))
t.start()
[thread.join() for thread in threads]
@timeit
def use_process():
li=range(1,100000000)
processes=
# 1). 開啟的程序數是有瓶頸的, 取決於cpu個數,
# 2). 如果處理的資料比較小, 不建議使用多程序,因為建立程序和銷毀程序需要時間;
# 3). 如果處理資料足夠大, 0《程序數《cpu個數;
for i in range(5):
p=multiprocessing.process(target=job,args=(li,))
p.start()
[process.join() for process in processes]
if __name__ == '__main__':
no_use_thread()
use_thread()
use_process()
#---->輸出:
no_use_thread函式執行的時間是8.29
use_thread函式執行的時間是8.42
use_process函式執行的時間是3.10
程序與多程序概念
程序 process 是計算機中程式關於某資料集合上的一次執行活動,是系統進行資源分配和排程的基本單位,是作業系統機結構基礎。狹義定義 程序是正在執行的程式的例項。在同一時間,同一作業系統中有兩個或兩個以上的程式處於執行狀態。php 提供了程序控制的擴充套件 pcntl。pcntl 實現了unix ...
多執行緒與多程序的理解
參考 執行緒是最小的執行單元,而程序由至少乙個執行緒組成。如何排程程序和執行緒,完全由作業系統決定,程式自己不能決定什麼時候執行,執行多長時間。多程序和多執行緒的程式涉及到同步 資料共享的問題,編寫起來更複雜。在unix linux下,可以使用fork 呼叫實現多程序。要實現跨平台的多程序,可以使用...
Python 多程序與程序池
fork方法是呼叫一次,返回兩次,原因在於作業系統將當前程序 父程序 複製出乙份程序 子程序 這兩個程序幾乎完全相同,於是fork方法分別在父程序和子程序中返回。子程序中永遠返回0,父程序中返回的是子程序的id。importos if name main print current process ...