進程建立的兩個方式
# 開啓進程的第一種方式:永遠先執行主進程的代碼
# 多線程模塊導入進程
from multiprocessing import Process
# 導入時間模塊
import time
# 定義一個task函數,name函數
def task(name):
"""
主進程
:param name:
:return:
"""
# 輸出xx is running
print(f'{name} is running')
# 睡2秒
time.sleep(2)
# 輸出xx is gone
print(f'{name} is gone')
# 在本模塊執行此方法
if __name__ == '__main__':
# 在Windows環境下,開啓進程必須在__name__ == '__main__'下面
# 開啓子進程的命令
# 建立一個進程對象p target=task目標是task函數,args=('zs',) 給name賦值zs
p = Process(target=task,args=('zs',)) # 元祖的形式
# 開啓一個子進程 start() 開啓命令
p.start() # 子進程會copy主進程的初始資料 至關於同時開啓子進程和主進程
# 這個信號操做系統接收到以後,會在內存中開闢一個子進程空間,而後再將主進程上全部數據copy加載到子進程,
# 而後再去調用cpu去執行
# 執行主進程
print('主程序-開始') # 只運行主進程和子進程,先執行主進程,開闢進程會很消耗內存
# 輸出:
# 主程序-開始
# zsis running
# zsis gone
# 睡3秒
time.sleep(3)
print('主進程-結束')
# 輸出:
# 主程序-開始
# zs is running
# zs is gone
# 主進程-結束
# 開啓進程的第二種方式:需重構父類
from multiprocessing import Process
import time
# 若是不進行實例化.name屬性默認有傳參,屬性值爲MyProcess1
# 建立一個類MyProcess 繼承Process
class MyProcess(Process):
# 直接實例化會報錯 須要重構父類 先執行父類的run再執行本身的run
# 實例化對象
def __init__(self,name):
# supper()重構父類
super().__init__()
# 屬性值爲name=屬性名name
self.name = name
# 定義一個run方法 實例化
def run(self):
# 輸出xx is running
print(f'{self.name} is running')
# 睡2秒
time.sleep(2)
# 輸出xx is gone
print(f'{self.name} is gone')
# 在本模塊執行此方法
if __name__ == '__main__':
# 實例化對象p 把zs給name
p = MyProcess('zs')
# 啓動子進程
p.start()
print('主進程-開始')
# 簡單應用
from multiprocessing import Process
import time
def task(name):
print(f'{name} is running')
time.sleep(1)
print(f'{name} is gone')
def task1(name):
print(f'{name} is running')
time.sleep(2)
print(f'{name} is gone')
def task2(name):
print(f'{name} is running')
time.sleep(3)
print(f'{name} is gone')
# 串行執行一個進程中執行三個任務 4.5秒
if __name__ == '__main__':
# 啓動時間=當前時間
start_time = time.time()
task('zs')
task1('zs2')
task2('zs3')
# 當前時間-啓動時間=運行的時間
print(f'結束時間{time.time()-start_time}')
# 輸出
# zs is running
# zs is gone
# zs2 is running
# zs2 is gone
# zs3 is running
# zs3 is gone
# 結束時間6.009660959243774
# 三個進程 併發或者並行的執行三個任務 3秒
if __name__ == '__main__':
start_time = time.time()
p1 = Process(target=task,args=('zs',))
p2 = Process(target=task1,args=('zs2',))
p1.start()
p2.start()
task2('zs3')
print(f'結束時間{time.time()-start_time}')
# 輸出
# zs3 is running
# zs is running
# zs2 is running
# zs is gone
# zs2 is gone
# zs3 is gone
# 結束時間3.009711742401123
進程的pid
# 導入os模塊
import os
# 導入time模塊
import time
# mac 命令行獲取全部的進程的pid號 ps-ef
# Windows 命令行獲取全部的進程的pid號 tasklist
# 代碼級別如何獲取一個進程pid號 os.getpid()
print(f'子進程:{os.getpid()}')
# 如何獲取父進程(主進程)的pid號 os.getppid()
print(f'主進程:{os.getppid()}')
time.sleep(5) # 睡50秒打開終端,找到Python進程的pid進行覈對
from multiprocessing import Process
import time
import os
def task(name): # 再執行子進程
print(f'子進程{os.getpid()}')
print(f'主進程{os.getppid()}')
if __name__ == '__main__':
# 建立一個進程對象
p = Process(target=task,args=('zs',))
p.start()
print(f'主進程的pid{os.getppid()}') # 先執行主進程
# 輸出:
# 子進程:6712
# 主進程:590
# 主進程的pid590
# 子進程6713
# 主進程6712
空間隔離
# 怎麼執行都是先執行主進程
# 加個sleep睡一會
# 空間隔離
# 子進程修改後的name與主進程的name沒有關係
from multiprocessing import Process
import os
import time
# 不可變
name = 'zs'
def task():
global name
name = 'ls'
print(f'子進程{name}') # ls
if __name__ == '__main__':
p = Process(target=task) # 建立一個進程對象
p.start()
time.sleep(3)
print(f'主進程{name}') # zs
# 輸出
# 子進程ls
# 主進程zs
# 可變的
lst = ['ww',]
def task():
lst.append('yy')
print(f'子進程{lst}') # ['ww','yy']
if __name__ == '__main__':
p = Process(target=task) # 建立一個進程對象
p.start()
time.sleep(3)
print(f'主進程{lst}') # ['ww']
# 輸出
# 子進程['ww', 'yy']
# 主進程['ww']
進程的其餘參數
from multiprocessing import Process
import time
# 殺死子進程 terminate()
def task(name):
print(f'{name} is running')
time.sleep(2)
print(f'{name} is gone')
if __name__ == '__main__':
p = Process(target=task,args=('zs',)) # 建立一個進程對象
p.start() # 啓動進程
p.terminate() # 殺死子進程
print('主進程')
# 輸出
# 主進程
# 只輸出主進程,子進程被殺死
from multiprocessing import Process
import time
def task(name):
print(f'{name} is running')
time.sleep(2)
print(f'{name} is gone')
if __name__ == '__main__':
p = Process(target=task, args=('zs',)) # 建立一個進程對象
p.start() # 啓動進程
time.sleep(1) # 睡1秒
p.terminate() # 殺死子進程
print('主進程')
# 輸出
# zs is running
# 主進程
# 先執行子進程睡一會,再殺死子進程,最後執行子進程
# 查看是否真的殺死子進程 子進程是否還活着is_alive()方法
from multiprocessing import Process
import time
def task(name):
print(f'{name} is running')
time.sleep(2)
print(f'{name} is gone')
if __name__ == '__main__':
p = Process(target=task,args=('zs',)) # 建立一個進程對象
p.start() # 啓動子進程
p.terminate() # 殺死子進程
p.join() # 阻塞 還能夠用sleep()
print(p.is_alive()) # 判斷子進程是否還活着 True活着 False死了
print('主進程')
# 輸出
# False
# 主進程
# 增長屬性 默認name屬性 Process屬性值
from multiprocessing import Process
import time
def task(name):
print(f'{name} is running')
time.sleep(2)
print(f'{name} is gone')
if __name__ == '__main__':
p = Process(target=task,args=('zs',),name ='alex') # 建立一個進程對象
p.start() # 啓動子進程
p.name = 'ls' # 添加屬性
print(p.name) # 打印name :ls
print('主進程')
# 輸出:ls
# 主進程
# zs is running
# zs is gone
守護進程
# 守護進程
# 子進程守護者主進程,只要主進程結束,子進程跟着結束 daemon=True
from multiprocessing import Process
import time
def task(name):
print(f'{name} is running')
time.sleep(2)
print(f'{name} is gone')
if __name__ == '__main__':
p = Process(target=task,args=('zs',)) # 建立一個進程對象p
# 將p子進程設置成守護進程,只要主進程結束,守護進程立刻結束
p.daemon = True # 在開啓子進程以前設置守護進程
p.start()# 開啓子進程
time.sleep(1) # 睡一會
print('主進程')
# 輸出
# zs is running
# 主進程
殭屍進程和孤兒進程
"""
# 殭屍進程 基於Unix環境(Linux,MacOs)
# 主進程等子進程完成以後,主進程再結束
# ***生命週期:
# 主進程時刻監測子進程的運行狀態,當子進程結束以後,一段時間以內,將子進程進行回收
# 爲何主進程不在子進程結束後立馬對其回收呢
# 1.主進程與子進程是異步關係,主進程沒法立刻捕獲子進程何時結束
# 2.若是子進程結束以後立刻在內存中釋放資源,主進程就沒有辦法監測子進程的狀態了
# ***Unix針對上面的問題,提供了一個機制
# 全部的子進程結束以後,立馬會釋放掉文件的操做連接,內存的大部分數據,
可是會保留一個一些內容:進程號,結束時間,運行狀態,等待主進程監測,回收
# 殭屍進程:
# 全部的子進程結束以後,在被主進程回收以前,都會進入殭屍狀態
# 殭屍進程的危害:
# 若是父進程不對殭屍進程進行回收(wait/waitpid),產生大量的殭屍進程
這樣就會佔用內存,佔用進程pid號
# 孤兒進程:
# 父進程因爲某種緣由結束了,可是子進程還在運行中,這樣這些子進程就變成了孤兒進程。
父進程若是結束了,全部的孤兒進程就會被init進程的回收,init就變成了父進程
# 如何解決殭屍進程:
# 父進程產生了大量子進程,可是不回收,這樣就會造成大量的殭屍進程,
解決方式就是直接殺死父進程,將全部的殭屍進程變成孤兒進程,進程由init進行回收
"""
from multiprocessing import Process
import time
import os
def task(name):
print(f'{name} is running')
print(f'主進程:{os.getppid()}')
print(f'子進程:{os.getpid()}')
time.sleep(50)
print(f'{name} is gone')
if __name__ == '__main__':
p = Process(target=task,args=('zs',))
p.start()
print('主程序-開始')
time.sleep(3)
print('主進程-結束')