進程控制(上)【Linux操作系統】

進程控制

寫時拷貝

本質是一種減少深拷貝的方法
Linux中有很多拷貝的場景都用得上寫時拷貝,下面以創建子進程時的寫時拷貝為例:

子進程被創建的時候:
會繼承父進程的mm_struct和頁表
所以子進程剛剛繼承時,父子進程的代碼和數據都是共享的

系統是如何知道子進程/父進程修改數據的時候要發生寫時拷貝的呢?
①父進程在使用fork創建子進程之前,就會把頁表中的數據區的權限改成r(只讀)
這樣子進程繼承到的頁表中的數據區就也是只讀的

②當子進程/父進程嘗試修改數據區中的數據時,就是修改只讀數據項,頁表就會報錯,就會觸發缺頁中斷

③系統發現缺頁中斷之后,就會檢測
1,如果發現用戶要修改的這個區域一定是只讀的,就把進程殺掉
2,如果這個區域一定是讀寫的,只是頁表中的權限設置成只讀的了,此時系統就會進行寫時拷貝
在這里插入圖片描述

所以:不止創建子進程寫時拷貝的時候是這種原理
只要可能發生寫時拷貝的數據被頁表管理著,就都可以通過這個原理實現寫時拷貝



錯誤碼

用來判斷進程任務執行是否成功,如果失敗了錯誤是什么

main函數的返回值其實是錯誤碼,是返回給父進程/操作系統的
在這里插入圖片描述
進程錯誤碼的的取值范圍是[0-255],即一個字節
因為使用wait/waitpid等待回收錯誤碼的時候,只給它留了8個比特位



進程中止

進程中止的方法:

①在main函數中return

②在任何地方使用exit函數[exit函數的參數就是錯誤碼,它的頭文件是stdio.h]

③_exit使用方法和exit一模一樣


exit與_exit的區別:

本質區別就是exit是用戶層的庫函數,_exit是內核層的系統調用
所以exit函數中,調用_exit中止進程之前,可以進行一些用戶層的收尾工作
比如:
exit中止進程時,會刷新用戶級緩沖區和內核級緩沖區
也就是如果輸出緩沖區中有數據,使用exit中止它會幫我們打印出來

_exit中止進程時,不會刷新用戶級緩沖區,只會刷新內核級緩沖區

②exit是庫里面的函數,是操作系統之外的操作,使用操作系統的資源時,只能對操作系統調用接口進行封裝
exit其實就封裝了_exit

_exit是系統調用接口,是操作系統內部的操作
在這里插入圖片描述

所以:
其實我們之前再使用c/c++等高級語言時,所說的緩沖區都是語言級(用戶級)的緩沖區

這個緩沖區里面的內容是存儲在c/c++的標準庫中的,即存儲在共享區的

不是存儲在操作系統中的內核級緩沖區
不然_exit中止進程時,就也能把緩沖區中信息輸出/輸入
但是因為語言級緩沖區在操作系統的上層,所以_exit中止進程后,內核緩沖區就關閉了,語言緩沖區中的數據沒辦法進入操作系統了
操作系統沒看見語言緩沖區中傳來信息,就以為里面沒有



進程等待

wait(不常用)

頭文件:sys/types.hsys/wait.h
返回值:pid_t[小于0說明回收失敗,大于0時回收成功,返回的是回收的子進程的pid]
參數:

作用:等待并回收任意一個子進程
在這里插入圖片描述


waitpid[常用]

頭文件:sys/types.hsys/wait.h
返回值:pid_t n
①n小于0,說明回收失敗/函數調用失敗
②n大于0,回收成功,返回的是成功回收的子進程的pid
③n等于0(只有非阻塞等待才會出現),則表示函數調用成功,但是子進程還沒執行完,還沒退出

參數1.pid_t pid

如果是子進程的pid,就表示指定等待這個子進程
如果是-1,就表示等待任意一個進程


參數2,int* status

如果傳nullptr則表示不需要獲取退出信息==

即:用戶自己定義一個int類型的變量
再把它的地址傳進waitpid里面,操作系統就會把進程的PCB中存儲的退出信息給status

status其實并不是一個整數,而是一個類似位圖的東西
因為進程結束,分兩種情況:
①正常退出,也就是通過main函數的return或者exit退出,這樣就可以返回退出碼
所以只有正常退出才能返回退出碼(錯誤碼)

②異常退出,也就是進程運行的途中,空指針訪問/野指針等直接導致進程崩潰了
這樣進程根本就運行不到返回退出碼的地方
但是異常退出,也會有自己的退出信號碼
[通過kill -l命令,可以看到Linux中所有的退出信號以及其對應的退出信號碼]

進程之所以會異常退出,是因為進程運行時出現了較嚴重的錯誤(野指針,除0等
操作系統識別到以后,在代碼還沒跑完的時候,就直接使用信號中止了進程


所以
status中不僅僅存儲了退出碼,還存儲了其他的退出信息

具體的:
status的:
①最低的7個比特位存儲退出信號值
②第8個比特位存儲core dump標志
③第9~16個比特位存儲退出碼
在這里插入圖片描述

宏:
WIFEXITED(status):
若為正常終止子進程返回的狀態,則為真(查看進程是否是正常退出)

WEXITSTATUS(status):
若WIFEXITED非零,提取子進程退出碼。(查看進程的退出碼)


參數3.標識是阻塞等待,還是非阻塞等待

如果該參數是0,表示阻塞式等待
如果為WNOHANG,表示非阻塞式等待



使用子進程完成任務的好處

①非阻塞等待或者創建多個子進程時,父子進程可以同時運行,父進程不用等子進程,提高并發度

②進程具有獨立性,所以如果子進程出了問題,不影響父進程

③數據快照,子進程被fork出來,繼承了父進程的PCB,頁表等東西之后
就獲取到了fork時父進程的數據
也就是對子進程從父進程那里獲取到的數據進行了快照
快照之后,其他任何進程對這一塊數據進行修改,這個子進程都“看不見”
因為寫時拷貝,或者說進程具有獨立性。所以數據快照之后,其他進程可以對這個數據任意修改

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/77104.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/77104.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/77104.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Flutter 強制橫屏

在 Flutter 中,可以通過設置 SystemChrome 來強制應用橫屏顯示。以下是實現這一功能的詳細步驟和代碼示例: 步驟 1:導入必要的包 確保在文件頂部導入了 services.dart 包,因為 SystemChrome 類位于該包中。 import package:flut…

Git完全指南:從入門到精通版本控制 ------- Git核心命令(6)

Git核心命令完全指南:從入門到高效協作 前言 在軟件開發領域,Git已成為現代版本控制的代名詞。據統計,全球超過90%的開發團隊使用Git進行代碼管理。然而,許多開發者僅停留在基礎命令的機械使用層面,未能真正掌握Git命…

關于Newtonsoft.Json

歷史 Newtonsoft.Json(也稱為 Json.NET)是由 James Newton - King 開發的一個開源的 JSON 處理庫,它于 2007 年首次發布。在早期,.NET 平臺缺乏一個強大且靈活的 JSON 處理工具,Newtonsoft.Json 應運而生,…

git reset詳解

一、git reset 的核心作用 用于 移動當前分支的 HEAD 指針 到指定的提交,并可選擇是否修改工作區和暫存區。 ?? 注意:若提交已被推送到遠程倉庫,強制重置(--hard)后需謹慎操作,避免影響協作。 二、三種模…

【unity游戲開發入門到精通——UGUI】CanvasScaler畫布縮放器組件

注意:考慮到UGUI的內容比較多,我將UGUI的內容分開,并全部整合放在【unity游戲開發——UGUI】專欄里,感興趣的小伙伴可以前往逐一查看學習。 文章目錄 一、CanvasScaler畫布縮放器組件是什么二、CanvasScaler的三種適配模式1、Cons…

Kubernetes控制平面組件:API Server Webhook 授權機制 詳解

云原生學習路線導航頁(持續更新中) kubernetes學習系列快捷鏈接 Kubernetes架構原則和對象設計(一)Kubernetes架構原則和對象設計(二)Kubernetes架構原則和對象設計(三)Kubernetes控…

Python自動化辦公

第五篇:Python自動化辦公:10行代碼搞定重復性工作 適合讀者:職場人士、數據分析師 | 閱讀時長:12分鐘 引言 每天重復處理Excel、PDF或郵件?Python可以幫你自動化這些枯燥任務,節省90%的時間。本文通過實際…

【3】k8s集群管理系列--包應用管理器helm之chart資源打包并推送到harbor鏡像倉庫

一、chart資源打包 helm package ./web-chart # 當前目錄會生成一個tgz的壓縮文件二、安裝help push插件(用于推送前面打包的文件,到鏡像倉庫) .1 下載help-push二進制文件 wget https://github.com/chartmuseum/helm-push/releases/down…

【SpringBoot Druid Mysql多數據源整合】

SpringBoot Druid Mysql多數據源整合 一、背景二、配置結果2.1 SpringBoot java 類配置2.1.1 啟動類配置2.1.2 java Config配置 2.2 SpringBoot yml 配置 三、mybatis插件配置3.1 PageHelper的yml配置3.2 mybatis設置自定義字段默認值 四、配置解釋 一、背景 公司項目需要連接另…

GGML源碼逐行調試(中)

目錄 前言1. 簡述2. 加載模型超參數3. 加載詞匯表4. 初始化計算上下文5. 初始化計算后端6. 創建模型張量7. 分配緩沖區8. 加載模型權重結語下載鏈接參考 前言 學習 UP 主 比飛鳥貴重的多_HKL 的 GGML源碼逐行調試 視頻,記錄下個人學習筆記,僅供自己參考&…

kubectl的使用

查看集群有多少節點 kubectl get nodes 獲取集群狀態的摘要信息(組件信息) kubectl get cs 查看所有命名空間下的所有pod的狀態和信息 kubectl get pods --all-namespaces 查看所有命名空間的狀態和信息 kubectl get namespaces /ns 查看kube-system…

git在分支上會退到某個指定的commit

1、在idea上先備份好分支(基于現有分支new branch) 2、在gitlab管理端刪除現有分支 3、在idea中大卡terminal,執行 git log 查看commit log ,找到要會退到的commit唯一碼,然后執行git reset 唯一碼 4、查看本地代碼狀態 git st…

動態路由, RIP路由協議,RIPv1,RIPv2

動態路由 1、回顧 路由:從源主機到目標主機的過程 源主機發送數據給目標主機,源主機會查看自身的路由信息 如果目標主機是自己同網段,源主機查看的是直連路由 如果目標主機和自己不同網段,源主機查看的是靜態路由、動態路由、默…

前端面試-工程化(webpack、vite)

Webpack 相關問題(25道) Webpack 的核心概念有哪些?(Entry、Output、Loader、Plugin、Module、Bundle)如何配置 Webpack 的多入口和多出口?Webpack 的 Tree Shaking 實現原理是什么?Loader 和 …

idea 2024 build菜單不見了

Q如題 idea 2024 新版UI添加build和recompile菜單 A如圖,右鍵頂部欄之后,點擊Add to Main Toolbar菜單,在里面就能找到Build菜單,添加接口。 Recompile菜單的話在Customize Toolbar中搜索添加才行。

【開源項目】Excel手撕AI算法深入理解(三):時序(RNN、mamba)

項目源碼地址:https://github.com/ImagineAILab/ai-by-hand-excel.git 一、RNN 1. RNN 的核心思想 RNN 的設計初衷是處理序列數據(如時間序列、文本、語音),其核心特點是: 隱藏狀態(Hidden State&#xff…

pycharm已有python3.7,如何新增Run Configurations中的Python interpreter為python 3.9

在 PyCharm 中,如果你已經安裝了 Python 3.9,并且希望在 Run Configurations 中新增一個 Python 3.9 的解釋器,可以按照以下步驟操作: 步驟 1:打開 PyCharm 設置 點擊 PyCharm 左上角的 File 菜單。選擇 Settings&am…

【H橋電機驅動電路原理】-學習筆記

工作原理 電路分析 這是一個由晶體管構成的 H 橋電機驅動電路 ,以下是對其各部分的介紹: 核心器件 晶體管:電路中使用了 PNP 型的 SS8550(Q5、Q6 )和 NPN 型的 SS8050(Q9、Q10、Q13、Q14 )。…

【家政平臺開發(49)】解鎖家政平臺上線密碼:服務器選型與配置全攻略

本【家政平臺開發】專欄聚焦家政平臺從 0 到 1 的全流程打造。從前期需求分析,剖析家政行業現狀、挖掘用戶需求與梳理功能要點,到系統設計階段的架構選型、數據庫構建,再到開發階段各模塊逐一實現。涵蓋移動與 PC 端設計、接口開發及性能優化,測試階段多維度保障平臺質量,…

驅動開發硬核特訓 · Day 10 (理論上篇):設備模型 ≈ 運行時的適配器機制

🔍 B站相應的視屏教程: 📌 內核:博文視頻 - 總線驅動模型實戰全解析 敬請關注,記得標為原始粉絲。 在 Linux 驅動開發中,設備模型(Device Model)是理解驅動架構的核心。而從軟件工程…