柚子快報(bào)邀請(qǐng)碼778899分享:運(yùn)維 【Linux】進(jìn)程概念
柚子快報(bào)邀請(qǐng)碼778899分享:運(yùn)維 【Linux】進(jìn)程概念
文章目錄
什么是進(jìn)程?描述進(jìn)程---PCB什么是PCB
task_struct當(dāng)中的內(nèi)容標(biāo)識(shí)符
多進(jìn)程創(chuàng)建總結(jié)
什么是進(jìn)程?
進(jìn)程是操作系統(tǒng)中的一個(gè)基本概念,它是正在運(yùn)行的程序的實(shí)例。進(jìn)程不僅僅是代碼,還包括代碼執(zhí)行時(shí)所需的資源和狀態(tài)信息。 簡(jiǎn)單來說進(jìn)程=程序的代碼和數(shù)據(jù)+內(nèi)核數(shù)據(jù)結(jié)構(gòu)(內(nèi)核數(shù)據(jù)結(jié)構(gòu)用于管理進(jìn)程的資源和狀態(tài)等信息)
描述進(jìn)程—PCB
由于上面我們說到進(jìn)程等于內(nèi)核數(shù)據(jù)結(jié)構(gòu)加上自己的代碼和數(shù)據(jù),這里的數(shù)據(jù)結(jié)構(gòu)在Linux中叫做task_struct,task_struct是PCB的一種。
什么是PCB
PCB是操作系統(tǒng)中用于管理每個(gè)進(jìn)程的重要數(shù)據(jù)結(jié)構(gòu)。它包含了操作系統(tǒng)需要的所有信息,用來跟蹤、控制和調(diào)度進(jìn)程。每個(gè)進(jìn)程都會(huì)對(duì)應(yīng)一個(gè)唯一的PCB,操作系統(tǒng)通過PCB來識(shí)別和管理進(jìn)程的狀態(tài)和資源。
首先我們知道一個(gè)程序在運(yùn)行時(shí)都是要先被加載到內(nèi)存中的,然后加載到內(nèi)存中之后由CPU進(jìn)行讀取數(shù)據(jù)。加載到內(nèi)存中,我們是不是只加載了程序的代碼,很顯然不是的,如果我們只加載代碼和數(shù)據(jù),那我們?cè)撛趺垂芾磉@個(gè)進(jìn)程呢?所以我們還需要一推數(shù)據(jù)來方便管理這個(gè)進(jìn)程,比如說這個(gè)進(jìn)程的狀態(tài),標(biāo)識(shí)符,優(yōu)先級(jí)等等信息,這些信息被合起來創(chuàng)建了一個(gè)task_struct,來管理這個(gè)進(jìn)程。 這里展示部分task_struct的代碼:
struct task_struct {
/*
* These are the only fields we actually need to create a task:
*/
struct list_head tasks; /* 指向同一進(jìn)程組中所有任務(wù)的列表頭 */
pid_t pid; /* 進(jìn)程ID */
int state; /* 進(jìn)程狀態(tài) */
unsigned int flags; /* 進(jìn)程標(biāo)志 */
struct task_struct __rcu *real_parent; /* 父進(jìn)程PCB指針 */
struct task_struct *parent; /* 父進(jìn)程PCB指針,即使父進(jìn)程已退出也不會(huì)為NULL */
struct list_head children; /* 子進(jìn)程鏈表 */
struct list_head sibling; /* 兄弟進(jìn)程鏈表 */
/*
* These fields are here for internal use. They should not be
* touched outside of the scheduler proper.
*/
struct thread_info *thread_info;
struct fs_struct *fs; /* 文件系統(tǒng)結(jié)構(gòu)體 */
struct files_struct *files; /* 打開文件結(jié)構(gòu)體 */
struct signal_struct *signal; /* 進(jìn)程信號(hào)管理結(jié)構(gòu)體 */
struct sighand_struct *sighand; /* 信號(hào)處理函數(shù)集合 */
struct nsproxy *nsproxy;
struct cred *cred;
struct cred *real_cred;
u64 start_time; /* 進(jìn)程開始時(shí)間 */
struct timer_list real_timer;
struct pid_link pids[PIDTYPE_MAX];
struct taskstats *stats; /* 與進(jìn)程相關(guān)的統(tǒng)計(jì)信息 */
可以看見管理進(jìn)程的代碼中有很多進(jìn)程的信息。
在task_struct中有一個(gè)指針指向下一個(gè)進(jìn)程,還有一個(gè)指針指向自己對(duì)應(yīng)的進(jìn)程
task_struct當(dāng)中的內(nèi)容
標(biāo)示符: 描述本進(jìn)程的唯一標(biāo)示符,用來區(qū)別其他進(jìn)程。狀態(tài): 任務(wù)狀態(tài),退出代碼,退出信號(hào)等。優(yōu)先級(jí): 相對(duì)于其他進(jìn)程的優(yōu)先級(jí)。程序計(jì)數(shù)器: 程序中即將被執(zhí)行的下一條指令的地址。內(nèi)存指針: 包括程序代碼和進(jìn)程相關(guān)數(shù)據(jù)的指針,還有和其他進(jìn)程共享的內(nèi)存塊的指針上下文數(shù)據(jù): 進(jìn)程執(zhí)行時(shí)處理器的寄存器中的數(shù)據(jù)[休學(xué)例子,要加圖CPU,寄存器]。I/O狀態(tài)信息: 包括顯示的I/O請(qǐng)求,分配給進(jìn)程的I/O設(shè)備和被進(jìn)程使用的文件列表。記賬信息: 可能包括處理器時(shí)間總和,使用的時(shí)鐘數(shù)總和,時(shí)間限制,記賬號(hào)等。其他信息
首先我們來說說標(biāo)識(shí)符信息。
標(biāo)識(shí)符
標(biāo)識(shí)符是什么?
先寫一段簡(jiǎn)單的死循環(huán)代碼。 用上面指令加管道查看指定進(jìn)程。
ps ajx | grep myexe
首先,ps ajx是查看所有的進(jìn)程,后面加上管道就可以查看指定的進(jìn)程 可以看見查看所有進(jìn)程的時(shí)候第一排是有頭部信息的,而我們的沒有,所以我們可以把頭部信息加上。
ps ajx | head -1 && ps ajx | grep myexe
這段指令就可以使得查看指定進(jìn)程的同時(shí)順便加上頭部信息了。 可以看見,這里的頭部信息有很多,pid就是我們所說的標(biāo)識(shí)符,標(biāo)識(shí)符具有唯一性,可以唯一的確定一個(gè)進(jìn)程,意思就是我們可以通過標(biāo)識(shí)符來查找進(jìn)程。
可以看見確實(shí)可以用pid來查看指定進(jìn)程,這里可以看見多出來一個(gè)bash進(jìn)程,通過觀察可以看見myexe的ppid和bash的pid是相同的,可以發(fā)現(xiàn)bash和myexe是父子進(jìn)程,bash是命令解釋器,myexe是bash的子進(jìn)程。意思就是說在啟動(dòng)myexe的時(shí)候,bash啟動(dòng)了一個(gè)myexe的子進(jìn)程。 ppid ppid是父進(jìn)程(parent pid)可以這樣理解
直到怎么查看進(jìn)程之后,我們應(yīng)該如何結(jié)束進(jìn)程呢?
第一種方式:Ctrl+c 第二種方式:kill+進(jìn)程標(biāo)識(shí)符
這兩種方式都可以結(jié)束進(jìn)程。
我們已經(jīng)知道了bash會(huì)創(chuàng)建一個(gè)子進(jìn)程來執(zhí)行我們的命令,那么我們?cè)撊绾问謩?dòng)創(chuàng)建一個(gè)子進(jìn)程呢?
通過上面的函數(shù)fork()可以手動(dòng)創(chuàng)建一個(gè)子進(jìn)程。 可以看見創(chuàng)建成功會(huì)給父進(jìn)程返回子進(jìn)程的pid,給子進(jìn)程返回0,如果創(chuàng)建失敗會(huì)返回-1。
1 #include
2 #include
3
4 int main()
5 {
6 pid_t id=fork();
7 while(1)
8 {
9 if(id>0)
10 {
11 printf("我是父進(jìn)程,pid:%d ,ppid:%d\n",getpid(),getppid());
12 sleep(1);
13 }
14 else if(id==0)
15 {
16 printf("我是子進(jìn)程,pid:%d ,ppid:%d\n",getpid(),getppid());
17 sleep(1);
18 }
19 }
20 return 0;
21 }
上面代碼可以創(chuàng)建子進(jìn)程,我們來看看現(xiàn)象。 運(yùn)行結(jié)果看看現(xiàn)象: 可以看見子進(jìn)程和父進(jìn)程都打印了,看看上面代碼,明明這是一個(gè)if和else if為什么會(huì)兩個(gè)條件同時(shí)成立呢?
因?yàn)檫@里創(chuàng)建了一個(gè)子進(jìn)程,子進(jìn)程和父進(jìn)程共享同一份代碼,但是數(shù)據(jù)是私有的,所以會(huì)產(chǎn)生這樣的結(jié)果,我們來驗(yàn)證一下是不是。
1 #include
2 #include
3
4 int gval;
5
6 int main()
7 {
8 pid_t id=fork();
9 while(1)
10 {
11 if(id>0)
12 {
13 printf("我是父進(jìn)程,pid:%d ,ppid:%d ,id:%d ,gval:%d\n",getpid(),getppid(),id,gval);
14 sleep(1);
15 }
16 else if(id==0)
17 {
18 printf("我是子進(jìn)程,pid:%d ,ppid:%d ,id:%d ,gval:%d\n",getpid(),getppid(),id,gval);
19 gaval++;
20 sleep(1);
21 }
22 }
23 return 0;
24 }
首先這里創(chuàng)建一個(gè)全局變量,子進(jìn)程負(fù)責(zé)++和讀取,但是父進(jìn)程只讀取,如果是同一份數(shù)據(jù)的話,那么全局變量?jī)蓚€(gè)應(yīng)該打出來是同一個(gè)值,這里我們運(yùn)行驗(yàn)證一下。 可以看見只有子進(jìn)程的++了,父進(jìn)程并沒有++,可以看見兩個(gè)進(jìn)程的數(shù)據(jù)是私有的,這里我們可以得出一個(gè)結(jié)論:兩個(gè)進(jìn)程之間是具有高度獨(dú)立性的。
驗(yàn)證完這個(gè)之后,我們?cè)撊绾蝿?chuàng)建多進(jìn)程呢?
多進(jìn)程創(chuàng)建
1 #include
2 #include
3 #include
4 #include
5 using namespace std;
6
7 int num=10;
8
9 void SubProcess()
10 {
11 while(true)
12 {
13 cout<<"I am sub process, pid:"< 14 sleep(1); 15 } 16 } 17 18 int main() 19 { 20 vector 21 for(int i=0;i 22 { 23 pid_t id=fork(); 24 //子進(jìn)程進(jìn)入 25 if(id==0) 26 { 27 SubProcess(); 28 } 29 //到這里只有父進(jìn)程 30 allchild.push_back(id); 31 } 32 cout< 33 for(auto child:allchild) 34 { 35 cout< 36 } 37 cout< 38 while(true) 39 { 40 cout<<"我是父進(jìn)程:pid:"< 41 sleep(1); 42 } 43 44 return 0; 45 } 看看對(duì)應(yīng)信息確實(shí)對(duì)應(yīng)起來了 可以看見確實(shí)創(chuàng)建了十個(gè)進(jìn)程。 總結(jié) 本文從進(jìn)程的基本概念入手,介紹了進(jìn)程的組成結(jié)構(gòu),尤其是PCB(進(jìn)程控制塊)的作用。通過分析 task_struct 的內(nèi)容,我們了解了進(jìn)程在內(nèi)核中的重要數(shù)據(jù)結(jié)構(gòu)如何幫助管理其狀態(tài)和資源。隨后,我們探討了多進(jìn)程的創(chuàng)建過程,并通過代碼實(shí)例展示了多進(jìn)程的實(shí)現(xiàn)??偟膩碚f,進(jìn)程是操作系統(tǒng)管理資源的關(guān)鍵單元,深入理解其結(jié)構(gòu)和機(jī)制對(duì)于系統(tǒng)級(jí)編程至關(guān)重要。 通過這篇文章,希望讀者能夠?qū)M(jìn)程的內(nèi)部運(yùn)作和管理有更加清晰的認(rèn)識(shí),為日后深入學(xué)習(xí)操作系統(tǒng)或編寫并發(fā)程序打下基礎(chǔ)。 柚子快報(bào)邀請(qǐng)碼778899分享:運(yùn)維 【Linux】進(jìn)程概念 精彩鏈接
本文內(nèi)容根據(jù)網(wǎng)絡(luò)資料整理,出于傳遞更多信息之目的,不代表金鑰匙跨境贊同其觀點(diǎn)和立場(chǎng)。
轉(zhuǎn)載請(qǐng)注明,如有侵權(quán),聯(lián)系刪除。