多進程(一)
1.進程建立的兩種方式
開啓進程的第一種方式:
from multiprocessing import Process
import time
def task(name):
print(f'{name} is running')
time.sleep(2)
print(f'{name} is done')
if __name__ == '__main__':
#windows環境,開啓進程必須在__name__ == '__main__'下
p = Process(target = task,args = ('alex',))
#建立一個進程對象
p.start()
#只是向操做系統發出一個開闢子進程的信號,而後就執行下一行了
#操做系統收到信號後,會從內存中開闢一個子進程空間,而後再將主進程全部數據copy到子進程,而後再調用cpu去執行(開闢子進程開銷很大),因此永遠會先執行主進程的代碼
print('主進程運行')
#主進程運行
#alex is running
#alex is done
開啓進程的第二種方式:
from multiprocessing import Process
import time
class MyProcess(Process):
def __init__(self,name):
super().__init__()
self.name = name
def run(self):
print(f'{self.name} is running')
time.sleep(2)
print(f'{self.name} is done')
if __name__ == '__main__':
p = MyProcess('alex')
p.start()
print('主進程運行')
#主進程運行
#alex is running
#alex is done
簡單應用:
from multiprocessing import Process
import time
def task(name):
print(f'{name} is running')
time.sleep(1)
print(f'{name} is done')
def task1(name):
print(f'{name} is running')
time.sleep(2)
print(f'{name} is done')
if __name__ == '__main__':
p1 = Process(target = task,args = ('alex',))
p2 = Process(target = task,args = ('tony',))
start_time = time.time()
p1.start()
p2.start()
#兩個進程,併發或者並行的執行三個任務
print(f'結束時間{time.time() - start_time}')
#結束時間0.03194904327392578
#alex is running
#tony is running
#alex is done
#tony is done
2.獲取進程pid
區份內存中的進程:
命令行:獲取全部進程的pid(process id): tasklist,
查找某個進程的pid: tasklist|findstr 進程名
代碼級別:
import os
print(os.getpid())
獲取父進程(主進程的pid):
import os
print(os.getppid())
3.驗證進程之間的空間隔離
from multiprocessing import Process
import time
name = 'alex'
def task():
global name
name = 'tom'
print(f'子進程:{name}')
if __name__ == '__main__':
p = Process(target = task)
p.start()
time.sleep(3)
print(f'主進程:{name}')
#子進程:tom
#主進程:alex
lst = [1,2]
def task():
global lst
lst.append(3)
print(f'子進程:{lst}')
if __name__ == '__main__':
p = Process(target = task)
p.start()
time.sleep(3)
print(f'主進程:{lst}')
#子進程:[1, 2, 3]
#主進程:[1, 2]
4.join方法
join:讓主進程等待子進程結束以後,再執行主進程
from multiprocessing import Process
import time
def task(name):
print(f'{name} is running')
time.sleep(2)
print(f'{name} is done')
if __name__ == '__main__':
p = Process(target = task,args = ('alex',))
p.start()
p.join()
print('主進程開始')
#alex is running
#alex is done
#主進程開始
多個子進程使用join,join就是阻塞,主進程有join,主進程下面的代碼一概不執行,直到進程執行完畢以後,在執行.
驗證1:
from multiprocessing import Process
import time
def task(name,sec):
print(f'{name} is running')
time.sleep(sec)
print(f'{name} is done')
if __name__ == '__main__':
start_time = time.time()
p1 = Process(target = task,args = ('alex',1))
p2 = Process(target = task,args = ('tom',2))
p3 = Process(target = task,args = ('tony,3'))
p1.start()
p2.start()
p3.start()
p1.join() #join只針對主進程,若是join下面屢次join,則不阻塞
p2.join()
p3.join()
print(f'主進程:{time.time() - start_time}')
#alex is running
#tom is running
#tony is running
#alex is done
#tom is done
#tony is done
#主進程:3.1952016353607178
驗證2:
from multiprocessing import Process
import time
def task(name,sec):
print(f'{name} is running')
time.sleep(sec)
print(f'{name} is done')
if __name__ == '__main__':
start_time = time.time()
p1 = Process(target = task,args = ('alex',1))
p2 = Process(target = task,args = ('tom',2))
p3 = Process(target = task,args = ('tony,3'))
p1.start()
p1.join()
p2.start()
p2.join()
p3.start()
p3.join()
print(f'主進程:{time.time() - start_time}')
#alex is running
#alex is done
#tom is running
#tom is done
#tony is running
#tony is done
#主進程:6.42280125617981
優化上面的代碼:
from multiprocessing import Process
import time
def task(name,sec):
print(f'{name} is running')
time.sleep(sec)
print(f'{name} is done')
if __name__ == '__main__':
start_time = time.time()
lst = []
for i in range(1,4):
p = Process(target = task,args = (i,))
lst.append(p)
p.start() #循環時間很快,基本能夠實現同時發出指令
for i in lst:
i.join()
print(f'主進程:{time.time() - start_time}')
5.進程的其餘屬性
from multiprocessing import Process
import time
def task(name):
print(f'{name} is running')
time.sleep(2)
print(f'{name} is done')
if __name__ == '__main__':
p = Process(target = task,args = ('alex',)name = 'tony')
p.start()
p.terminate() #殺死子進程,沒有阻塞則子程序還沒運行就被殺死
print(P.is_alive()) #看子進程是否還活着,輸出True/False
print(p.name) #輸出以前給p添加的name屬性
print("主進程運行")
6.守護進程
守護進程:
子進程守護主進程,只要主進程結束,子進程跟着就結束
from multiprocessing import Process
import time
def task(name):
print(f'{name} is running')
time.sleep(2)
print(f'{name} is done')
if __name__ == '__main__':
p = Process(target = task,args = ('alex',))
p.daemon = True #將子進程p設置成守護進程,主進程結束,子進程也結束
p.start()
#p.daemon = True #必定要在子進程開啓以前設置,不然報錯
time.sleep(1)
print('主進程運行')
#alex is running
#主進程運行