文章目錄
- 多任務編程
- 進程
- 進程的優先級
- 父子進程
- 進程相關的函數
- os.getpid()
- os.getppid()
- os._exit(status)
- sys.exit([status])
- 僵尸進程
- 處理僵尸進程的方法
- os.wait()
- os.waitpid(pid, option)
- 創建二級子進程處理
- 在父進程中使用信號處理的方法,忽略子進程發來的信號
- 孤兒進程
多任務編程
可以有效的利用計算機資源,同時執行多個任務
進程
進程就是程序在計算機中一次執行的過程
進程和程序的區別:
程序是一個靜態文件的描述,不占計算機的系統資源
進程是一個動態的過程,占有CPU、內存等資源,有一定的生命周期
同一個程序的不同執行過程即為不同的進程
問題1:什么決定了進程的創建
1)用戶通過應用層程序進行進程的創建申請
2)調用操作系統接口進行進程創建
3)告知系統內核創建新的進程提供給應用層使用
問題2:進程如何占有CPU
1)同一個內核同一時刻只能運行一個進程
2)多個進程對內核資源進行搶占,由操作系統內核進行分配
3)哪個進程占有計算機內核,我們稱為該進程占有CPU的時間片
問題3:進程在運行過程中的形態和附帶內容
1)PCB(進程控制塊):在linux和unix操作系統中,進程創建后會在內存中開辟一塊空間存放進程的相關信息,這個空間稱之為PCB
2)PID:在操作系統中進程的唯一標識,是一個大于0的正整數,由系統自動分配
ps -aux 查看進程信息
虛擬內存:每個進程占有4G內存地址空間,這里的內存指的是虛擬內存
進程狀態:
三態
就緒態: 進程具備運行條件,等待系統分配處理器以便運行
運行態:進程占有cpu處于運行狀態
等待態:又稱為阻塞態或者睡眠態,指進程不具備運行條件,正在等待某些條件的達成
五態
就緒態: 進程具備運行條件,等待系統分配處理器以便運行
運行態:進程占有cpu處于運行狀態
等待態:又稱為阻塞態或者睡眠態,指進程不具備運行條件,正在等待某些條件的達成
新建:創建一個進程的過程,直接表現為執行某個程序或者在程序中創建新的進程
終止:進程執行結束,完成回收的過程
D: 等待態,不可中斷等待態
S: 等待態,可中斷等待態
T: 等待態,暫停狀態
R: 運行態
Z: 僵尸態
+: 前臺進程
N: 低優先級的進程
<: 高優先級的進程
l: 有進程鏈接
s: 會話組
進程的優先級
優先級往往決定了一個進程的執行權限和占有系統資源的優先程度
top: 動態查看系統進程運行情況
linux系統中優先級范圍為-20—19,其中-20優先級最高,19優先級最低,0為平均狀態,用戶創建進程默認優先級為0
nice: 以指定的優先級運行某一個進程
nice -9 ./while.py 以9的優先級運行程序
sudo nice --9 ./while.py 以-9的優先級運行程序
renice n PID: 修改一個正在運行的進程的優先級
renice 8 4277 將4277號進程優先級修改為8
父子進程
在系統中除了初始化進程之外,每個進程都是由父進程創建的,每個進程有一個唯一的父進程,可能有多個子進程
需求:兩間不相關事情希望同時來做
# test.py文件
import time
def fun1():
time.sleep(6)
print('做完第一件事情')
def fun2():
time.sleep(4)
print('做完第二件事情')
方案一:寫兩個進程,分別承擔不同的事情,各自執行
分析:1. 兩個程序比較麻煩
2. 無法確定兩個程序應該在什么時間開始運行
方案二:寫一個程序,在程序中指定位置調用接口來創建新的進程
實現方法: os.fork()函數實現
fork()
功能:創建一個新的進程
參數:無
返回值:
小于0 表示進程創建失敗
等于0 表示在子進程中fork的返回值為0
大于0 在父進程中fork的返回值大于0
-
fork是os模塊函數,只能在linux和unix下使用
測試1:父進程中fork之前的內容,子進程同樣也會復制,但是父子進程空間內容的修改不會相互影響
測試2:父子進程在執行上互不影響,理論上不一定誰先執行
測試3:子進程雖然復制父進程的空間,但也有自己獨特的特性,比如自己的pid,進程控制塊,進程棧等。父進程中fork的返回值即為創建的子進程的pid號
# os模塊提供了大量和系統相關的功能函數接口
# os模塊的使用是系統相關的,在不同的系統中可能使用方法不同
import os
import time
# 創建新的進程
pid = os.fork()
if pid < 0:
print('create process failed')
elif pid == 0:
print('pid:')
print(pid)
while True:
time.sleep(0.8)
print('This is the new process')
else:
# 父進程中pid為子進程的PID號
print('parent pid:')
print(pid)
while True:
time.sleep(1)
print('This is the parent process')
print('The process end')
需求解決:
import os
import time
# 導入test中的函數
from test import *
# 創建新的進程
pid = os.fork()
if pid < 0:
print('create process failed')
elif pid == 0:
fun1()
else:
fun2()
進程相關的函數
os.getpid()
功能:獲取當前進程的PID號
import os
pid = os.fork()
if pid < 0:
print('create process failed')
elif pid == 0:
print('Child process:')
print('當前進程的PID:', os.getpid())
else:
print('Parent process')
print('pid:', pid)
os.getppid()
功能:獲取當前進程父進程的PID號
os._exit(status)
功能:用來結束一個進程
參數:一個數字,表示進程的退出狀態,通常0表示正常退出進程,其他數字表示非正常退出
sys.exit([status])
功能:用來結束一個進程, 如果處理了拋出的異常,則不結束進程
參數:一個數字,表示進程的退出狀態,同上
還可以是一個字符串,則在進程退出時會打印這個字符串
import os
import sys
# 拋出異常進程不結束
try:
sys.exit('over')
except SystemExit as e:
print(e)
print('process over')
僵尸進程
子進程先于父進程退出,父進程沒有對子進程的退出做相應的處理,此時子進程就會變為僵尸進程
影響:進程退出后,仍有部分信息殘留在內存中占用空間,大量的僵尸進程會影響系統運行,所以應該盡量避免僵尸進程的產生。
處理僵尸進程的方法
- 讓父進程先退出(不好控制)
- 父進程處理子進程的退出(阻塞父進程的運行)
os.wait()
功能:等待子進程退出進行處理
參數:無
返回值:返回一個包含兩個元素的元組,第一個是退出的子進程的PID號,第二個是子進程的退出狀態
- wait是一個阻塞函數,即進程處于等待狀態,等待某種條件的達成才會繼續運行
import os
import sys
from time import sleep
pid = os.fork()
if pid < 0:
print('create process failed')
elif pid == 0:
print('child process...')
sleep(2)
sys.exit(6) # 子進程退出
else:
# wait 阻塞等待子進程的退出
p, status = os.wait()
print('parent process...')
print('p, status:', p, status)
os.waitpid(pid, option)
功能:同wait, 處理子進程退出,使其不會成為僵尸
參數:
pid=-1表示等待任意子進程退出
pid大于0表示等待指定進程號的子進程退出
option=0 表示阻塞等待
option=WNOHANG 表示非阻塞狀態
返回值:同wait
創建二級子進程處理
# 創建二級子進程解決僵尸進程
import os
# 創建一級子進程
pid = os.fork()
if pid < 0:
print('create process failed')
elif pid == 0:
# 創建二級子進程
p = os.fork()
if p < 0:
print('process failed')
elif p == 0:
print('做二級子進程任務')
else:
# 一級子進程退出,使二級子進程成為孤兒
os._exit(0)
else:
# 等待一級子進程退出
os.wait()
print('做父進程任務')
在父進程中使用信號處理的方法,忽略子進程發來的信號
signal(SIGCHLD, SIG_IGN)
孤兒進程
父進程先于子進程退出,此時子進程就會變為孤兒進程
影響:當一個進程變為孤兒進程,系統會自動的使用一個進程成為孤兒進程的父進程。當孤兒進程退出時,該系統進程會自動回收孤兒,使他不會成為僵尸。所以孤兒進程對系統資源沒有什么影響。
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
