python第九篇:Python进程
Python進(jìn)程
接下來我主要按照下圖中思維導(dǎo)圖上的關(guān)鍵點(diǎn)對進(jìn)程和線程進(jìn)行一個(gè)總結(jié)
進(jìn)程知識點(diǎn)總結(jié):
一、Python進(jìn)程
1.概念
程序和進(jìn)程:
程序:是可執(zhí)行文件,是靜態(tài)的,占據(jù)磁盤空間,程序運(yùn)行的時(shí)候會產(chǎn)生進(jìn)程。
進(jìn)程:進(jìn)程是一個(gè)動態(tài)的過程,占有計(jì)算機(jī)資源,有一定的生命周期。
并行和并發(fā):
并行:多個(gè)任務(wù)利用計(jì)算機(jī)多核資源在同時(shí)執(zhí)行,此時(shí)多個(gè)任務(wù)為并行關(guān)系。
并發(fā):計(jì)算機(jī)在同時(shí)處理多個(gè)問題的時(shí)候,內(nèi)核在不同的任務(wù)之間不斷的切換達(dá)到好像多個(gè)任務(wù)被同時(shí)執(zhí)行的結(jié)果,實(shí)際上每個(gè)時(shí)刻只有一個(gè)任務(wù)占據(jù)內(nèi)核。
CPU時(shí)間片:
CPU時(shí)間片:如果一個(gè)進(jìn)程占有CPU此時(shí)我們稱該進(jìn)程占有CPU時(shí)間片,多個(gè)進(jìn)程任務(wù)會輪流占有CPU時(shí)間片形成并發(fā)效果。
進(jìn)程控制塊(PCB):
進(jìn)程控制塊:進(jìn)程創(chuàng)建后會自動在內(nèi)存開辟一塊空間存放進(jìn)程的基本信息。
僵尸進(jìn)程和孤兒進(jìn)程:
孤兒進(jìn)程:父進(jìn)程先于子進(jìn)程退出,此時(shí)子進(jìn)程就會成為孤兒進(jìn)程。孤兒進(jìn)程會被系統(tǒng)進(jìn)程收養(yǎng),此時(shí)系統(tǒng)進(jìn)程就會成為該進(jìn)程的新父進(jìn)程。
僵尸進(jìn)程:子進(jìn)程先于父進(jìn)程退出,父進(jìn)程沒有處理子進(jìn)程的退出狀態(tài),此時(shí)子進(jìn)程就會成為僵尸進(jìn)程。僵尸進(jìn)程結(jié)束時(shí)會存留部分的PCB在內(nèi)存中,大量的僵尸進(jìn)程會浪費(fèi)系統(tǒng)的資源。
那么如何避免僵尸進(jìn)程?
1、阻塞父進(jìn)程,等待子進(jìn)程退出的時(shí)候父進(jìn)程可以及時(shí)處理子進(jìn)程的退出狀態(tài)
2、新建一個(gè)二級子進(jìn)程,二級子進(jìn)程的父進(jìn)程及時(shí)退出,這時(shí)候二級子進(jìn)程就會成為孤兒進(jìn)程,孤兒進(jìn)程會被系統(tǒng)進(jìn)程收養(yǎng),同時(shí)孤兒進(jìn)程永遠(yuǎn)不會成為僵尸進(jìn)程。
2.進(jìn)程屬性
p.name # 進(jìn)程名稱
p.pid #進(jìn)程PID(Process ID)
p.daemon #默認(rèn)值為False 表示主進(jìn)程退出不會影響子進(jìn)程
如果設(shè)置為True 則主進(jìn)程退出子進(jìn)程也會退出
p.is_alive() # 查看進(jìn)程是否在生命周期
3.進(jìn)程方法
3.1、獲取當(dāng)前進(jìn)程的PID
os.getpid()
3.2、獲取父進(jìn)程的PID
os.getppid()
4.進(jìn)程的創(chuàng)建和關(guān)閉
進(jìn)程的關(guān)閉:
'''
進(jìn)程退出
功能 : 退出一個(gè)進(jìn)程
參數(shù) : 表示自定義的進(jìn)程退出狀態(tài) 整數(shù)
'''
os._exit(status)
'''
功能 : 退出一個(gè)進(jìn)程
參數(shù) : 默認(rèn)為0
如果傳入一個(gè)整數(shù)則同 _exit()
傳入一個(gè)字符串。則在對出時(shí)打印該字符串
'''
sys.exit([status])
1、使用os.fork()創(chuàng)建進(jìn)程
注意:
1、子進(jìn)程會復(fù)制父進(jìn)程的全部代碼和內(nèi)存空間(父子的內(nèi)存空間是相互獨(dú)立的)
2、子進(jìn)程從fork的下一句開始執(zhí)行
3、if elif else 結(jié)構(gòu)判斷fork返回值的不同使得父子進(jìn)程執(zhí)行不同幾乎是固定搭配
4、父子進(jìn)程各自獨(dú)立運(yùn)行,運(yùn)行順序不一定
import os
from time import sleep
'''
功能:創(chuàng)建進(jìn)程
參數(shù):無
返回值:失敗返回一個(gè)負(fù)數(shù)
成功:在原進(jìn)程中返回新進(jìn)程的PID,在新進(jìn)程中返回0
'''
pid =os.fork()
if pid<0:
print("Create process error")
elif pid ==0:
sleep(1)
print("Child PID",os.getpid())
print("Get parent PID",os.getppid())
else:
print("Parent PID",os.getpid())
print("Get child PID",pid)
2、使用multiprocessing模塊創(chuàng)建進(jìn)程
from multiprocessing import Process
# 編寫進(jìn)程函數(shù)
def fun():
print("子進(jìn)程事件")
# 創(chuàng)建進(jìn)程對象
p = Process(target = fun)
# 啟動進(jìn)程
p.start()
# 回收進(jìn)程 父進(jìn)程阻塞等待回收子進(jìn)程 想當(dāng)os.wait()
p.join()
5.進(jìn)程之間的通信(常用的為消息隊(duì)列和套接字)
進(jìn)程空間相對獨(dú)立,所以說不同的進(jìn)城之間需要專門的方法進(jìn)行通信。常用的通信方法有如下幾種:管道、消息隊(duì)列、共享內(nèi)存、信號量、套接字
5.1、通信管道(Pipe)
通信原理:在內(nèi)存中開辟管道空間,生成管道操作對象,多個(gè)進(jìn)程使用同一管道對象進(jìn)行讀寫即可實(shí)現(xiàn)通信。
from multiprocessing import Process,Pipe
import os,time
# 創(chuàng)建管道對象
'''
功能 : 創(chuàng)建管道
參數(shù) : 默認(rèn)表示雙向管道
如果設(shè)置為False 則為單向管道
返回值 : 表示管道兩端的讀寫對象
如果是雙向管道則兩端都可以讀寫
如果是單向管道則fd1只讀 fd2只寫
'''
fd1,fd2 = Pipe()
'''
fd1.send
功能:向管道寫入內(nèi)容
參數(shù):要寫入的數(shù)據(jù)
* 可以寫入python的數(shù)據(jù)類型
'''
def fun(name):
time.sleep(3)
fd1.send(name)
jobs = []
for i in range(5):
p = Process(target = fun,args=(i,))
jobs.append(p)
p.start()
for i in range(5):
'''
功能 : 從管道讀取內(nèi)容
返回值:讀到的內(nèi)容
*當(dāng)管道為空則阻塞
'''
data =fd2.recv()
print(data)
for i in jobs:
i.join()
5.2、消息隊(duì)列
原路:在內(nèi)存中建立隊(duì)列模型,進(jìn)程通過隊(duì)列對象將消息存入隊(duì)列,或者從隊(duì)列中取出消息,完成進(jìn)程間的通信。
from multiprocessing import Queue
from time import sleep
# 創(chuàng)建消息隊(duì)列
'''
功能: 創(chuàng)建隊(duì)列對象
參數(shù): 表示隊(duì)列中最多存放多少個(gè)消息
返回值 : 隊(duì)列對象
'''
q =Queue(3)
'''
q.put(data,[block,timeout])
功能 : 向隊(duì)列存入消息
參數(shù) : data 要存入的內(nèi)容 python數(shù)據(jù)
block 默認(rèn)隊(duì)列滿時(shí)會阻塞,設(shè)置為False則為非阻塞
timeout 超時(shí)檢測
'''
q.put(1)
sleep(1)
print(q.empty())
q.put(2)
q.put(3)
print(q.full())
'''
q.get([block,timeout])
功能 : 從隊(duì)列獲取消息
參數(shù) : block 默認(rèn)當(dāng)隊(duì)列為空時(shí)阻塞,設(shè)置為False則為非阻塞
timeout 超時(shí)檢測
'''
print(q.get())
print(q.qsize())
q.close()
5.3、進(jìn)程間通信之共享內(nèi)存(Value,Array)
通信原理:在內(nèi)存空間開辟一個(gè)區(qū)域,對多個(gè)進(jìn)程可見,進(jìn)程可寫入內(nèi)容或者讀取內(nèi)容,但是每次寫入的內(nèi)容會覆蓋之前的內(nèi)容。
from multiprocessing import Value,Array
'''
功能:開辟共享內(nèi)存空間
參數(shù):
ctype 字符串,表示共享內(nèi)存中藥存儲的數(shù)據(jù)類型
常用類型: int --> 'i'
float --> 'f'
char(bytes) --> 'c'
obj 共享內(nèi)存中放入的初始化數(shù)據(jù)
obj.value 對該屬性的修改和使用即對共享內(nèi)存數(shù)據(jù)的修改和使用
'''
obj = Value(ctype, obj)
''
功能:創(chuàng)建共享內(nèi)存
參數(shù):
ctype 要存儲的數(shù)據(jù)類型
obj 存入一個(gè)結(jié)構(gòu)化數(shù)據(jù)(列表 bytes字符串) 表示共享內(nèi)存中的初始化數(shù)據(jù)
傳入正整數(shù) 表示在共享內(nèi)存中開辟指定大小的數(shù)據(jù)空間
返回值:共享內(nèi)存對象
可以通過遍歷獲取每個(gè)值,支持索引操作
如果存入的是字符串,可以通過obj.value直接打印整個(gè)字符串
'''
obj = Array(ctype,obj)
5.4、信號量
原理:給定一個(gè)數(shù)量,多個(gè)進(jìn)程均可見。多個(gè)進(jìn)程可以通過方法操作數(shù)量,達(dá)到協(xié)同工作的目的。
''' 功能:創(chuàng)建信號量對象 參數(shù):信號量的初始值 返回值:信號量對象 ''' from multiprocessing import Semaphore sem = Semaphore(num) sem.acquire() # 將信號量減1 當(dāng)信號量為0會阻塞 sem.release() # 將信號量加1 sem.get_value() # 獲取信號量數(shù)量
6.使用進(jìn)程池管理進(jìn)程
產(chǎn)生原因: 如果有大量任務(wù)需要多進(jìn)程完成,則可能要頻繁的創(chuàng)建刪除進(jìn)程,此時(shí)給計(jì)算機(jī)帶來的壓力較大。
原理 : 創(chuàng)建一定量的進(jìn)程作為進(jìn)程池,用來處理事件。事件處理完畢后不銷毀進(jìn)程,而是繼續(xù)等待處理其他的事件。直到所有待處理事件結(jié)束再統(tǒng)一銷毀進(jìn)程。增加進(jìn)程的重復(fù)利用,降低資源消耗。
使用方法
1. 創(chuàng)建進(jìn)程池,方式適當(dāng)?shù)倪M(jìn)程
2. 將要做的事件放入進(jìn)程池等待隊(duì)列
3. 不斷取事件使用進(jìn)程池中進(jìn)程執(zhí)行,直到所有事件處理完畢
4. 關(guān)閉進(jìn)程池,回收進(jìn)程
from multiprocessing import Pool
Pool(processes)
功能 : 創(chuàng)建進(jìn)程池對象
參數(shù) : 指定進(jìn)程池中進(jìn)程的數(shù)據(jù)量,默認(rèn)根據(jù)系統(tǒng)自動判定
pool.apply_async(func,args,kwds)
功能:使用進(jìn)程池中的進(jìn)程執(zhí)行相應(yīng)函數(shù)
參數(shù): func 進(jìn)程事件函數(shù)
args 元組 給func按位置傳參
kwds 字典 給func按鍵值傳參
返回值 : 返回函數(shù)事件對象
pool.apply(func,args,kwds)
功能:使用進(jìn)程池中的進(jìn)程執(zhí)行相應(yīng)函數(shù)
參數(shù): func 進(jìn)程事件函數(shù)
args 元組 給func按位置傳參
kwds 字典 給func按鍵值傳參
pool.close()
功能 : 關(guān)閉進(jìn)程池,不能再添加新的事件
pool.join()
功能:阻塞等待回收進(jìn)程池進(jìn)程
pool.map(func,iter)
功能:將要做的事件加入進(jìn)程池
參數(shù) : func 事件函數(shù)
iter 迭代對象
返回值: 函數(shù)的返回值列表
總結(jié)
以上是生活随笔為你收集整理的python第九篇:Python进程的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: WIN10平板 传递优化文件能否删除
- 下一篇: android实现前置后置摄像头相互切换