进程相关概念、C程序的空间分配
進(jìn)程的定義:
“進(jìn)程”是操作系統(tǒng)的最基本、最重要的概念之一。但迄今為止對(duì)這一概念還沒有一個(gè)確切的統(tǒng)一的描述。下面給出幾種對(duì)進(jìn)程的定義描述。
進(jìn)程是程序的一次執(zhí)行。進(jìn)程是可以并行執(zhí)行的計(jì)算。進(jìn)程是一個(gè)程序與其使用的數(shù)據(jù)在處理機(jī)上順序執(zhí)行時(shí)發(fā)生的活動(dòng)。進(jìn)程是程序在一個(gè)數(shù)據(jù)集合上的運(yùn)行過程。它是系統(tǒng)進(jìn)行資源分配和調(diào)度的一個(gè)獨(dú)立單位。
進(jìn)程的特征:
- 動(dòng)態(tài)性:是程序的一次執(zhí)行;
- 發(fā)性:進(jìn)程是可以并發(fā)執(zhí)行;
- 獨(dú)立性:是系統(tǒng)進(jìn)行資源分配和調(diào)度的一個(gè)獨(dú)立單位;
- 異步性:進(jìn)程間的相互制約,使進(jìn)程執(zhí)行具有間隙;
- 結(jié)構(gòu)性:進(jìn)程是具有結(jié)構(gòu)的。
進(jìn)程與程序的主要區(qū)別:
(1)程序是永存的;進(jìn)程是暫時(shí)的,是程序在數(shù)據(jù)集上的一次執(zhí)行,有創(chuàng)建有撤銷,存在是暫時(shí)的;
(2)程序是靜態(tài)的觀念,進(jìn)程是動(dòng)態(tài)的觀念;
(3)進(jìn)程具有并發(fā)性,而程序沒有;
(4)進(jìn)程是競(jìng)爭(zhēng)計(jì)算機(jī)資源的基本單位,程序不是。
(5)進(jìn)程和程序不是一一對(duì)應(yīng)的: 一個(gè)程序可對(duì)應(yīng)多個(gè)進(jìn)程即多個(gè)進(jìn)程可執(zhí)行同一程序; 一個(gè)進(jìn)程可以執(zhí)行一個(gè)或幾個(gè)程序。
進(jìn)程概念和程序概念最大的不同之處在于:
(1)進(jìn)程是動(dòng)態(tài)的,而程序是靜態(tài)的。
(2)進(jìn)程有一定的生命期,而程序是指令的集合,本身無“運(yùn)動(dòng)”的含義。沒有建立進(jìn)程的程序不能作為1個(gè)獨(dú)立單位得到操作系統(tǒng)的認(rèn)可。
(3)1個(gè)程序可以對(duì)應(yīng)多個(gè)進(jìn)程,但1個(gè)進(jìn)程只能對(duì)應(yīng)1個(gè)程序。進(jìn)程和程序的關(guān)系猶如演出和劇本的關(guān)系。
如何查看系統(tǒng)中有哪些進(jìn)程:
使用ps指令查看,在實(shí)際工作中,配合grep來查找程序中是否存在某一個(gè)進(jìn)程。
ps命令:
ps命令用于查看系統(tǒng)中的進(jìn)程狀態(tài),格式為“ps [參數(shù)]”。
ps命令的參數(shù)以及作用:
| -a | 顯示所有進(jìn)程(包括其他用戶的進(jìn)程) |
| -u | 用戶以及其他詳細(xì)信息 |
| -x | 顯示沒有控制終端的進(jìn)程 |
Linux系統(tǒng)中時(shí)刻運(yùn)行著許多進(jìn)程,如果能夠合理地管理它們,則可以優(yōu)化系統(tǒng)的性能。在Linux系統(tǒng)中,有5種常見的進(jìn)程狀態(tài),分別為運(yùn)行、中斷、不可中斷、僵死與停止,其各自含義如下所示。
R(運(yùn)行):進(jìn)程正在運(yùn)行或在運(yùn)行隊(duì)列中等待。
當(dāng)執(zhí)行ps aux命令后通常會(huì)看到如表2-7所示的進(jìn)程狀態(tài),表2-7中只是列舉了部分輸出值,而且正常的輸出值中不包括中文注釋。
top命令:
top命令用于動(dòng)態(tài)地監(jiān)視進(jìn)程活動(dòng)與系統(tǒng)負(fù)載等信息,其格式為top。
top命令相當(dāng)強(qiáng)大,能夠動(dòng)態(tài)地查看系統(tǒng)運(yùn)維狀態(tài),完全將它看作Linux中的“強(qiáng)化版的Windows任務(wù)管理器”。
ps -aux|grep 加所要查找的進(jìn)程相關(guān)信息
其中|相當(dāng)于管道,grep相當(dāng)于濾網(wǎng),信息從管道流下經(jīng)過濾網(wǎng)查找自己想要的信息。
以下是使用ps查看進(jìn)程: fhn@ubuntu:~/jincheng$ psPID TTY TIME CMD13580 pts/0 00:00:00 bash13757 pts/0 00:00:00 psfhn@ubuntu:~/jincheng$ ps -aux USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND root 1 0.0 0.3 225324 6108 ? Ss Jun27 0:30 /sbin/init auto noprompt root 2 0.0 0.0 0 0 ? S Jun27 0:00 [kthreadd] root 3 0.0 0.0 0 0 ? I< Jun27 0:00 [rcu_gp] root 4 0.0 0.0 0 0 ? I< Jun27 0:00 [rcu_par_gp] root 6 0.0 0.0 0 0 ? I< Jun27 0:00 [kworker/0:0H-kb] root 9 0.0 0.0 0 0 ? I< Jun27 0:00 [mm_percpu_wq] root 10 0.0 0.0 0 0 ? S Jun27 0:01 [ksoftirqd/0] root 11 0.0 0.0 0 0 ? I Jun27 1:17 [rcu_sched] root 12 0.0 0.0 0 0 ? S Jun27 0:01 [migration/0] root 13 0.0 0.0 0 0 ? S Jun27 0:00 [idle_inject/0] root 14 0.0 0.0 0 0 ? S Jun27 0:00 [cpuhp/0] root 15 0.0 0.0 0 0 ? S Jun27 0:00 [cpuhp/1] root 16 0.0 0.0 0 0 ? S Jun27 0:00 [idle_inject/1] root 17 0.0 0.0 0 0 ? S Jun27 0:01 [migration/1] root 18 0.0 0.0 0 0 ? S Jun27 0:00 [ksoftirqd/1] root 20 0.0 0.0 0 0 ? I< Jun27 0:00 [kworker/1:0H-kb] root 21 0.0 0.0 0 0 ? S Jun27 0:00 [cpuhp/2] root 22 0.0 0.0 0 0 ? S Jun27 0:00 [idle_inject/2] root 23 0.0 0.0 0 0 ? S Jun27 0:01 [migration/2] root 24 0.0 0.0 0 0 ? S Jun27 0:00 [ksoftirqd/2] root 26 0.0 0.0 0 0 ? I< Jun27 0:00 [kworker/2:0H-kb] root 27 0.0 0.0 0 0 ? S Jun27 0:00 [cpuhp/3] root 28 0.0 0.0 0 0 ? S Jun27 0:00 [idle_inject/3]什么是進(jìn)程標(biāo)識(shí)符:
系統(tǒng)給每個(gè)進(jìn)程定義了一個(gè)唯一標(biāo)識(shí)該進(jìn)程的非負(fù)正數(shù),稱作進(jìn)程標(biāo)識(shí)符。進(jìn)程標(biāo)識(shí)符可以簡(jiǎn)單的表示為主進(jìn)程表中的一個(gè)索引。當(dāng)某一進(jìn)程終止后,其標(biāo)識(shí)符可以重新用作另一進(jìn)程的標(biāo)識(shí)符。不過,在任何時(shí)刻,一個(gè)標(biāo)識(shí)符所代表的進(jìn)程是唯一的。系統(tǒng)把標(biāo)識(shí)符 0 和 1 保留給系統(tǒng)的兩個(gè)重要進(jìn)程。進(jìn)程 0 是調(diào)度進(jìn)程,它按一定的原則把處理機(jī)分配給進(jìn)程使用。進(jìn)程 1 是初始化進(jìn)程,它是程序/sbin/init 的執(zhí)行。進(jìn)程 1 是 UNIX 系統(tǒng)那其它進(jìn)程的祖先,并且是進(jìn)程結(jié)構(gòu)的最終控制者。
進(jìn)程屬性-標(biāo)識(shí)符:
每個(gè)進(jìn)程都有6個(gè)重要的ID:進(jìn)程ID、父進(jìn)程ID、有效用戶ID、有效組ID、實(shí)際用戶ID和實(shí)際組ID。這6個(gè)標(biāo)識(shí)符保存在進(jìn)程的PCB中。
什么叫父進(jìn)程和子進(jìn)程:
- 父進(jìn)程:指已創(chuàng)建一個(gè)或多個(gè)子進(jìn)程的進(jìn)程。在UNIX里,除了進(jìn)程0以外的所有進(jìn)程都是由其他進(jìn)程使用系統(tǒng)調(diào)用fork創(chuàng)建的,這里調(diào)用fork創(chuàng)建新進(jìn)程的進(jìn)程即為父進(jìn)程,而相對(duì)應(yīng)的為其創(chuàng)建出的進(jìn)程則為子進(jìn)程,因而除了進(jìn)程0以外的進(jìn)程都只有一個(gè)父進(jìn)程,但一個(gè)進(jìn)程可以有多個(gè)子進(jìn)程。
- 子進(jìn)程:指的是由另一進(jìn)程(對(duì)應(yīng)稱之為父進(jìn)程)所創(chuàng)建的進(jìn)程。子進(jìn)程繼承了對(duì)應(yīng)的父進(jìn)程的大部分屬性,如文件描述符。在Unix中,子進(jìn)程通常為系統(tǒng)調(diào)用fork的產(chǎn)物。在此情況下,子進(jìn)程一開始就是父進(jìn)程的副本,而在這之后,根據(jù)具體需要,子進(jìn)程可以借助exec調(diào)用來鏈?zhǔn)郊虞d另一程序。
C程序的存儲(chǔ)空間是如何分配的?
大佬博客:堆和棧詳解
程序運(yùn)行時(shí)的內(nèi)存分區(qū)主要分為BSS段、數(shù)據(jù)段、代碼段、堆、棧
- BSS段:Block Started by Symbol,一般是指存放程序中未初始化的全局變量的一塊內(nèi)存區(qū)域。BSS段屬于靜態(tài)內(nèi)存分配。
- 數(shù)據(jù)段:data segment,一般是指用來存放程序中已初始化的全局變量的一塊內(nèi)存區(qū)域。 static 意味著 在數(shù)據(jù)段中 存放變量,數(shù)據(jù)段屬于靜態(tài)內(nèi)存分配。
- 代碼段:code segment/text segment,通常是指用來存放程序執(zhí)行代碼的一塊內(nèi)存區(qū)域。這部分區(qū)域的大小在程序運(yùn)行前就已經(jīng)確定,并且內(nèi)存區(qū)域通常屬于只讀,某些架構(gòu)也允許代碼段為可寫,即允許修改程序。在代碼段中,也有可能包含一些 只讀的常數(shù)變量 ,例如字符串常量等。程序段為程序代碼在內(nèi)存中的映射。一個(gè)程序可以在內(nèi)存中有多個(gè)副本。
- 堆:heap,堆是用于存放進(jìn)程運(yùn)行中被動(dòng)態(tài)分配的內(nèi)存段,它的大小并不固定,可動(dòng)態(tài)擴(kuò)張或縮減。當(dāng)進(jìn)程調(diào)用malloc/free等函數(shù)分配內(nèi)存時(shí),新分配的內(nèi)存就被動(dòng)態(tài)添加到堆上(堆被擴(kuò)張)/釋放的內(nèi)存從堆中被剔除(堆被縮減)。
- 棧:stack,棧又稱堆棧,存放程序的局部變量(但不包括static聲明的變量, static 意味著 在數(shù)據(jù)段中 存放變量)。除此以外,在函數(shù)被調(diào)用時(shí),棧用來傳遞參數(shù)和返回值。由于棧的先進(jìn)后出特點(diǎn),所以棧特別方便用來保存/恢復(fù)調(diào)用現(xiàn)場(chǎng)。儲(chǔ)動(dòng)態(tài)內(nèi)存分配,需要程序員手工分配,手工釋放。
如上圖所示:紅色箭頭指向的是代碼段,粉色箭頭指向的在函數(shù)外被初始化過的變量,我們叫做數(shù)據(jù)段(main函數(shù)里面初始化的變量屬于局部變量,其生命周期和全局變量一樣,所以上方圖片int a=0屬于數(shù)據(jù)段,圖片有點(diǎn)錯(cuò)誤),黃色箭頭指向的在函數(shù)外沒有被初始化的變量(BSS段),自己編寫好的C代碼編譯后會(huì)生成一個(gè)可執(zhí)行文件,當(dāng)我們運(yùn)行這個(gè)可執(zhí)行文件是操作系統(tǒng)會(huì)給程序劃分一段內(nèi)存空間,這段內(nèi)存空間就相當(dāng)于左邊那副黃色的圖所示,從高地址到低地址會(huì)把代碼文件里面的代碼段載入到對(duì)應(yīng)的地址,其中malloc申請(qǐng)的空間是在堆上面,棧存放的內(nèi)容是:函數(shù)調(diào)用返回的地址、相關(guān)參數(shù)、函數(shù)里面的局部變量和寄存器內(nèi)容等。自動(dòng)變量(也就是局部變量)以及每次函數(shù)調(diào)用所需要的保存的信息都存放在此段中,每次函數(shù)調(diào)用時(shí),其返回地址以及調(diào)用者的環(huán)境信息(例如某些機(jī)器寄存器的值)都存放在棧中。然后最近被調(diào)用的函數(shù)在棧上為其自動(dòng)和臨時(shí)變量分配存儲(chǔ)空間,通過這種方式使用棧可以遞歸調(diào)用C函數(shù),遞歸函數(shù)每次調(diào)用自身時(shí),就使用一個(gè)新的棧幀,因此函數(shù)調(diào)用實(shí)例中的變量不會(huì)影響到另一個(gè)函數(shù)調(diào)用實(shí)例中的變量。左圖中:最上面是命令行和環(huán)境變量也就是argc和argv這些東西。
總結(jié)
以上是生活随笔為你收集整理的进程相关概念、C程序的空间分配的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 图像基本运算概述型
- 下一篇: fork、vfork、wait、wait