Hike News
Hike News

Python模塊-multiprocessing多進程

Preface:

  • Python中同時間一個進程只能有一個線程通過GIL交給其中一個CPU執行
  • 同時間要完成多任務能透過創建多進程(multiprocessing)交給不同CPU執行
  • 進程:
    • 程序是未運行的EXE檔:其還沒運行之前,無法調度系統的資源(內存、設備如滑鼠鍵盤等)
    • 進程是運行起來的程序檔案:其能調度系統資源,稱為進程
      • 操作系統分配資源的基本單位

Introduction:

  • multiprocessing是Python中多進程的管理模塊
  • 其使用方法與多線程(threading)模塊類似,只是環境不同而已
  • 創建進程所耗費的資源較創建線程大

Notice:

  • 進程結束時,必須對每個進程物件調用join()方法,相當於wait,否則進程將成為僵屍進程
  • 進程之間完全獨立不能共享數據,除非透過第三方進行交流,例如Queue,Pipe (優先考慮)
  • 進程之間應避免共享的資源,只要透過第三方進行交流,必定會降低執行程序的效率
  • windows系統下,如想啟動一個子進程,與進程相關的語句要寫在if __name__ == "__main__"之下

Usage:

Example I: (直接調用)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
from multiprocessing import Process

def func(name):
print('My name is %s'%name)

if __name__ == "__main__":
process_list = []

for i in range(3):
pro = Process(target=func, args=('taroballz',)) # 創建一個進程物件
process_list.append(pro)
pro.start() # 進程開始工作

for each_process in process_list:
each_process.join() #等待子進程們回到主進程

print('The end of mulitprocessing performance')
  • 根據以上的code可表示創建了三個子進程,加上主進程共有四個進程於四個CPU上執行不同工作
  • 要是執行的進程數大於CPU本身的執行緒數,CPU會使用切換的方式來完成多進程運作

Example II: (繼承類調用)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
from multiprocessing import Process

class New_Process(Process):
def __init__(self):
super(New_Process,self).__init__()

def run(self): #將進程要執行的任務寫在run方法中
print("My Process_name is %s"%self.name)

if __name__ == "__main__":
process_list=[]
for i in range(3):
pro = New_Process()
process_list.append(pro)
pro.start()
for each_process in process_list:
each_process.join()

print('The end of mulitprocessing performance')

Relation between Processes:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
from multiprocessing import Process
import os

def show_process_info(processname):
print(processname)
print("process __name__ is",__name__)
print("parents process ID(PPID): ",os.getppid())
print("self process ID(PID): ",os.getpid(),'\n')

if __name__ == "__main__":
show_process_info('main_process')
for i in range(2):
proc = Process(target=show_process_info,args=("Process-%d"%i, ))
proc.start()
proc.join()
print("The End ! !")

執行結果如下所示

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
main_process
process __name__ is __main__
parents process ID(PPID): 3460
self process ID(PID): 13512

Process-0
process __name__ is __mp_main__
parents process ID(PPID): 13512
self process ID(PID): 13636

Process-1
process __name__ is __mp_main__
parents process ID(PPID): 13512
self process ID(PID): 11412

The End ! !

從結果我們可以知道新創建的子進程都為主進程所創造 且 隸屬於原本的主進程
(兩個子進程的PPID皆屬於主進程自身的PID)

Reference:

http://www.cnblogs.com/yuanchenqi/articles/5745958.html