一、程序存儲(chǔ)空間
本節(jié)說(shuō)的空間主要是指內(nèi)存空間,即程序如何分配和使用內(nèi)存。
1.1 C語(yǔ)言程序存儲(chǔ)空間
可執(zhí)行程序,而不是源代碼。
C語(yǔ)言程序的存儲(chǔ)空間包括以下幾個(gè)主要部分:
-
代碼段(Text Segment): 也稱正文段, 代碼段是存儲(chǔ)C程序的機(jī)器代碼的區(qū)域。它包含了程序的指令集,這些指令由編譯器生成,并且在程序執(zhí)行時(shí)按照順序執(zhí)行。代碼段通常是只讀的,這意味著程序在運(yùn)行時(shí)不能修改它。
-
數(shù)據(jù)段(Data Segment): 數(shù)據(jù)段用于存儲(chǔ)全局變量、靜態(tài)變量和常量數(shù)據(jù)。這些數(shù)據(jù)在程序運(yùn)行期間存在,并且可以被程序的不同函數(shù)訪問(wèn)。數(shù)據(jù)段通常分為初始化數(shù)據(jù)段(.data)和未初始化數(shù)據(jù)段(.bss)。初始化數(shù)據(jù)段存儲(chǔ)已初始化的全局變量和常量數(shù)據(jù),而未初始化數(shù)據(jù)段存儲(chǔ)未初始化的全局變量(被自動(dòng)初始化為0或空指針)。
-
堆(Heap): 堆是動(dòng)態(tài)分配的內(nèi)存區(qū)域,用于存儲(chǔ)程序在運(yùn)行時(shí)動(dòng)態(tài)分配的內(nèi)存塊。堆內(nèi)存由程序員顯式分配和釋放,通常使用標(biāo)準(zhǔn)庫(kù)函數(shù)(如
malloc()
和free()
)來(lái)進(jìn)行管理。堆內(nèi)存的分配和釋放可以在程序運(yùn)行時(shí)動(dòng)態(tài)發(fā)生,因此它的大小和生存期不容易預(yù)測(cè)。 -
棧(Stack): 棧用于存儲(chǔ)函數(shù)的局部變量、函數(shù)參數(shù)和函數(shù)調(diào)用的返回地址。每當(dāng)函數(shù)被調(diào)用時(shí),一個(gè)新的棧幀(stack frame)會(huì)被創(chuàng)建,用于存儲(chǔ)函數(shù)的上下文信息。當(dāng)函數(shù)返回時(shí),棧幀會(huì)被銷毀。棧是一個(gè)后進(jìn)先出(LIFO)的數(shù)據(jù)結(jié)構(gòu),通常由操作系統(tǒng)管理。
- 每個(gè)部分還有更加細(xì)致的劃分,比如常量區(qū)和全局區(qū)。
- 前面列舉的是程序運(yùn)行的時(shí)候會(huì)被加載到內(nèi)存中的部分。還有一些其他的段,在程序開發(fā)和調(diào)試期間很有用,比如:
- 符號(hào)表段(Symbol Table Section): 符號(hào)表是一個(gè)數(shù)據(jù)結(jié)構(gòu),它包含了程序中定義的符號(hào)(如變量名、函數(shù)名等)與其在可執(zhí)行文件中的地址之間的映射關(guān)系。符號(hào)表通常位于可執(zhí)行文件的一個(gè)獨(dú)立段中,以便在調(diào)試和分析期間進(jìn)行訪問(wèn)。它有助于調(diào)試器查找變量或函數(shù)的地址,以及生成堆棧跟蹤信息。
- 調(diào)試信息段(Debug Information Section): 調(diào)試信息段包含了程序的調(diào)試信息,如源代碼位置、變量名、數(shù)據(jù)結(jié)構(gòu)的布局等。這些信息用于生成符號(hào)化的錯(cuò)誤消息、斷點(diǎn)設(shè)置和源代碼級(jí)別的調(diào)試。調(diào)試信息通常位于可執(zhí)行文件的一個(gè)單獨(dú)段中,例如DWARF格式或COFF格式。
- 字符串表段(String Table Section): 字符串表段包含了可執(zhí)行文件中使用的所有字符串,包括符號(hào)表中的符號(hào)名稱、調(diào)試信息中的源代碼文件路徑等。這有助于減小可執(zhí)行文件的大小并提高效率,因?yàn)樗梢员苊庵貜?fù)存儲(chǔ)相同的字符串。
- 重定位表段(Relocation Table Section): 重定位表段包含了程序中需要在加載時(shí)進(jìn)行動(dòng)態(tài)鏈接的地址重定位信息。這些信息指示了在可執(zhí)行文件中的哪些位置需要進(jìn)行符號(hào)解析和地址重定位。重定位表在動(dòng)態(tài)鏈接期間使用,以確保程序在不同的內(nèi)存位置上正確運(yùn)行。
查看各部分大小的命令:
root@CQUPTLEI:~/LinuxC/CLanguage# size time
text data bss dec hex filename
1603 600 8 2211 8a3 time
- text 表示代碼段的大小。
- data 表示數(shù)據(jù)段的大小。
- bss 表示未初始化的數(shù)據(jù)段(BSS段)的大小。
- dec 表示十進(jìn)制總大小。
- hex 表示十六進(jìn)制總大小。
- filename 是程序的文件名。
另外對(duì)于運(yùn)行的程序,可以使用pmap查看內(nèi)存映射情況(即各個(gè)部分位于內(nèi)存地址的哪個(gè)位置,大小如何)。
解釋:
- 000055d0e02d2000 到 000055d0e02d6000 是程序的代碼段和數(shù)據(jù)段,可執(zhí)行和可讀寫。
- 000055d0e1b0d000 是程序的堆,可讀寫。
- 00007f852513c000 到 00007f852532a000 是共享的動(dòng)態(tài)鏈接庫(kù)(libc-2.31.so 和 ld-2.31.so)的內(nèi)存映射,具有不同的權(quán)限和大小。
- 00007fff3f8dd000 到 00007fff3f9d7000 是進(jìn)程的棧,可讀寫。
- ffffffffff600000 是內(nèi)核的虛擬內(nèi)存地址范圍,通常不可執(zhí)行。
通過(guò)地址高低、權(quán)限、占用內(nèi)存大小來(lái)判斷。也可以使用其他命令。
1.2 用戶空間和內(nèi)核空間
用戶空間(User Space) 和 內(nèi)核空間(Kernel Space) 是指操作系統(tǒng)中的兩個(gè)不同的內(nèi)存區(qū)域,用于存放不同類型的程序代碼和數(shù)據(jù),并具有不同的特權(quán)級(jí)別和訪問(wèn)權(quán)限。這兩個(gè)空間在操作系統(tǒng)中的分隔是為了提高系統(tǒng)的安全性和穩(wěn)定性。
以下是關(guān)于用戶空間和內(nèi)核空間的主要特點(diǎn)和區(qū)別:
用戶空間(User Space):
-
應(yīng)用程序執(zhí)行區(qū)域: 用戶空間是用于存放用戶級(jí)別的應(yīng)用程序代碼和數(shù)據(jù)的區(qū)域。大多數(shù)應(yīng)用程序的執(zhí)行發(fā)生在用戶空間。
-
特權(quán)級(jí)別低: 用戶空間中的代碼和數(shù)據(jù)運(yùn)行在較低的特權(quán)級(jí)別下,通常是用戶模式(
User Mode
)或非特權(quán)模式。這意味著用戶程序不能直接訪問(wèn)底層硬件資源或進(jìn)行敏感的系統(tǒng)操作。 -
有限的權(quán)限: 用戶空間中的程序?qū)τ谙到y(tǒng)資源(如硬件設(shè)備、內(nèi)核數(shù)據(jù)結(jié)構(gòu)等)的訪問(wèn)受到限制。程序必須通過(guò)系統(tǒng)調(diào)用來(lái)請(qǐng)求內(nèi)核執(zhí)行特權(quán)操作,例如文件操作、網(wǎng)絡(luò)通信等。
-
錯(cuò)誤隔離: 用戶空間的程序通常不能直接影響整個(gè)系統(tǒng)的穩(wěn)定性。如果一個(gè)用戶空間的應(yīng)用程序崩潰或出現(xiàn)錯(cuò)誤,通常不會(huì)導(dǎo)致整個(gè)系統(tǒng)崩潰。
內(nèi)核空間(Kernel Space):
-
操作系統(tǒng)核心區(qū)域: 內(nèi)核空間是操作系統(tǒng)核心(內(nèi)核)的執(zhí)行區(qū)域,其中包含了操作系統(tǒng)的核心代碼和數(shù)據(jù)結(jié)構(gòu)。操作系統(tǒng)內(nèi)核負(fù)責(zé)管理系統(tǒng)資源、進(jìn)程調(diào)度、設(shè)備驅(qū)動(dòng)程序等任務(wù)。
-
特權(quán)級(jí)別高: 內(nèi)核空間中的代碼和數(shù)據(jù)運(yùn)行在較高的特權(quán)級(jí)別下,通常是內(nèi)核模式(
Kernel Mode
)或特權(quán)模式。這使得內(nèi)核可以直接訪問(wèn)系統(tǒng)的底層硬件資源和進(jìn)行特權(quán)操作。 -
無(wú)限的權(quán)限: 內(nèi)核空間中的代碼具有無(wú)限制的權(quán)限,可以執(zhí)行任何操作系統(tǒng)功能,并且可以訪問(wèn)系統(tǒng)的所有資源。(當(dāng)然了,并非所有硬件資源都可以無(wú)限訪問(wèn),需要芯片廠商開放給你才行)
-
系統(tǒng)關(guān)鍵性: 內(nèi)核空間中的代碼對(duì)于整個(gè)系統(tǒng)的穩(wěn)定性至關(guān)重要。內(nèi)核必須設(shè)計(jì)得穩(wěn)定且不容易受到用戶空間程序的惡意或錯(cuò)誤行為的干擾。
用戶空間和內(nèi)核空間的分隔是為了提高系統(tǒng)的安全性和穩(wěn)定性。用戶空間用于存放應(yīng)用程序代碼和數(shù)據(jù),而內(nèi)核空間包含操作系統(tǒng)內(nèi)核的核心代碼和數(shù)據(jù)。用戶程序通過(guò)系統(tǒng)調(diào)用等接口來(lái)請(qǐng)求內(nèi)核執(zhí)行特權(quán)操作,以訪問(wèn)底層資源。這種分隔使得操作系統(tǒng)能夠保護(hù)系統(tǒng)資源并隔離用戶程序的錯(cuò)誤,從而提高了系統(tǒng)的可靠性和安全性。
在傳統(tǒng)的操作系統(tǒng)設(shè)計(jì)中,主要有兩個(gè)關(guān)鍵的內(nèi)存空間,即用戶空間和內(nèi)核空間,用于分離用戶應(yīng)用程序和操作系統(tǒng)內(nèi)核的執(zhí)行環(huán)境和權(quán)限。然而,一些特殊的操作系統(tǒng)或安全機(jī)制可能引入其他內(nèi)存區(qū)域或權(quán)限級(jí)別。
以下是一些可能存在的其他內(nèi)存區(qū)域或權(quán)限級(jí)別:
中斷上下文(Interrupt Context): 中斷上下文是操作系統(tǒng)內(nèi)核在響應(yīng)硬件中斷時(shí)運(yùn)行的上下文。這個(gè)上下文通常具有比用戶空間更高的特權(quán)級(jí)別,因?yàn)閮?nèi)核需要能夠處理硬件中斷并采取適當(dāng)?shù)拇胧?。中斷上下文不同于用戶空間和內(nèi)核空間,因?yàn)樗怯捎布录|發(fā)的。
超級(jí)用戶/特權(quán)級(jí)別(Supervisor/Privileged Mode): 一些操作系統(tǒng)或處理器體系結(jié)構(gòu)可能支持多個(gè)特權(quán)級(jí)別,例如用戶模式、內(nèi)核模式和超級(jí)用戶模式。超級(jí)用戶模式通常具有更高的權(quán)限,可以執(zhí)行特權(quán)操作,如修改頁(yè)表或直接訪問(wèn)硬件寄存器。這種多級(jí)特權(quán)級(jí)別的設(shè)計(jì)可以增強(qiáng)操作系統(tǒng)的安全性和隔離性。
用戶模式切換(User Mode Switch): 在多任務(wù)操作系統(tǒng)中,內(nèi)核可能會(huì)在不同任務(wù)之間進(jìn)行用戶模式切換。這涉及到保存和恢復(fù)任務(wù)的上下文,以便在任務(wù)之間切換時(shí)能夠保持執(zhí)行狀態(tài)。這種切換可能涉及到額外的內(nèi)存區(qū)域來(lái)存儲(chǔ)任務(wù)上下文。
內(nèi)核模塊(Kernel Module): 一些操作系統(tǒng)允許動(dòng)態(tài)加載內(nèi)核模塊,這些模塊是在內(nèi)核空間中運(yùn)行的,但它們的加載和卸載過(guò)程可能涉及到特殊的內(nèi)存區(qū)域。
1.3 用戶模式和內(nèi)核模式
用戶模式(User Mode
)和內(nèi)核模式(Kernel Mode
)是操作系統(tǒng)和處理器體系結(jié)構(gòu)中的兩種不同特權(quán)級(jí)別或特權(quán)模式,它們用于控制程序?qū)ο到y(tǒng)資源的訪問(wèn)和執(zhí)行權(quán)限。
用戶模式(User Mode):
-
較低特權(quán)級(jí)別: 用戶模式是處理器的一種較低特權(quán)級(jí)別,通常用于執(zhí)行普通用戶應(yīng)用程序。在用戶模式中,應(yīng)用程序的執(zhí)行受到限制,不能直接訪問(wèn)底層硬件資源或執(zhí)行特權(quán)操作。
-
受限制的系統(tǒng)資源訪問(wèn): 應(yīng)用程序在用戶模式下運(yùn)行時(shí),其訪問(wèn)系統(tǒng)資源(如文件、設(shè)備、內(nèi)存)受到操作系統(tǒng)的控制和限制。應(yīng)用程序必須通過(guò)系統(tǒng)調(diào)用等接口來(lái)請(qǐng)求內(nèi)核執(zhí)行特權(quán)操作,以訪問(wèn)受保護(hù)的資源。
-
異常處理: 如果應(yīng)用程序執(zhí)行了非法或無(wú)效的操作,例如訪問(wèn)受保護(hù)的內(nèi)存區(qū)域,處理器會(huì)生成異常,將控制權(quán)轉(zhuǎn)移到內(nèi)核模式下的操作系統(tǒng)內(nèi)核,由內(nèi)核處理異常。
內(nèi)核模式(Kernel Mode):
-
較高特權(quán)級(jí)別: 內(nèi)核模式是處理器的一種較高特權(quán)級(jí)別,通常用于執(zhí)行操作系統(tǒng)內(nèi)核的代碼。在內(nèi)核模式中,內(nèi)核擁有最高的特權(quán),可以直接訪問(wèn)和控制系統(tǒng)的底層硬件資源。
-
無(wú)限制的系統(tǒng)資源訪問(wèn): 內(nèi)核模式下的操作系統(tǒng)內(nèi)核可以無(wú)限制地訪問(wèn)系統(tǒng)的各種資源,包括硬件設(shè)備、內(nèi)存管理、中斷處理等。內(nèi)核模式允許執(zhí)行特權(quán)指令,以完成各種系統(tǒng)管理任務(wù)。
-
異常處理和系統(tǒng)調(diào)用: 內(nèi)核模式下的操作系統(tǒng)內(nèi)核負(fù)責(zé)處理異常情況,如硬件故障、非法指令執(zhí)行等。此外,內(nèi)核模式下的操作系統(tǒng)內(nèi)核還響應(yīng)并執(zhí)行系統(tǒng)調(diào)用,以滿足用戶程序的特權(quán)操作請(qǐng)求。
拿個(gè)微軟的圖看把:
二、內(nèi)核調(diào)用-系統(tǒng)調(diào)用-C語(yǔ)言庫(kù)函數(shù)
2.1 系統(tǒng)調(diào)用和內(nèi)核調(diào)用
系統(tǒng)調(diào)用(System Call
)和內(nèi)核調(diào)用(Kernel Call
)都是操作系統(tǒng)內(nèi)核提供給用戶空間程序的接口,用于訪問(wèn)操作系統(tǒng)核心功能的方法。它們?cè)试S應(yīng)用程序執(zhí)行需要特權(quán)級(jí)別或操作系統(tǒng)提供的服務(wù),如文件操作、網(wǎng)絡(luò)通信、進(jìn)程管理等。
雖然它們有相似之處,但它們?cè)谝恍┓矫嬗兴煌?/p>
系統(tǒng)調(diào)用(System Call):
-
用戶空間和內(nèi)核空間分離: 系統(tǒng)調(diào)用是用戶空間和內(nèi)核空間之間的接口。用戶空間程序通過(guò)系統(tǒng)調(diào)用請(qǐng)求內(nèi)核執(zhí)行某些任務(wù)。
-
高層接口: 系統(tǒng)調(diào)用通常是高層次的接口,提供了相對(duì)較簡(jiǎn)單的、面向應(yīng)用程序的方式來(lái)訪問(wèn)內(nèi)核功能。例如,C庫(kù)(libc)提供了許多系統(tǒng)調(diào)用的包裝函數(shù),以便程序員更容易地使用它們。
-
通常使用函數(shù)調(diào)用的方式: 系統(tǒng)調(diào)用通常通過(guò)函數(shù)調(diào)用的方式來(lái)觸發(fā),例如C語(yǔ)言中的
read()
、write()
、fork()
等函數(shù)就是系統(tǒng)調(diào)用的例子。 -
具有安全性和權(quán)限控制: 系統(tǒng)調(diào)用是操作系統(tǒng)對(duì)用戶空間的安全性和權(quán)限控制的重要門戶。內(nèi)核會(huì)驗(yàn)證用戶是否有執(zhí)行特定系統(tǒng)調(diào)用的權(quán)限,并確保用戶程序不能直接訪問(wèn)內(nèi)核的數(shù)據(jù)結(jié)構(gòu)。
內(nèi)核調(diào)用(Kernel Call):
-
更低級(jí)別的接口: 內(nèi)核調(diào)用通常是更低級(jí)別的接口,允許用戶程序直接調(diào)用內(nèi)核的功能。這種調(diào)用可能涉及到內(nèi)核內(nèi)部數(shù)據(jù)結(jié)構(gòu)和功能,因此需要更謹(jǐn)慎的使用。
-
通常使用匯編或特定編程語(yǔ)言: 內(nèi)核調(diào)用通常不是以高級(jí)語(yǔ)言函數(shù)的形式提供,而是以底層的方式實(shí)現(xiàn),可能需要使用匯編語(yǔ)言或特定的編程語(yǔ)言來(lái)進(jìn)行調(diào)用。
-
較少的安全性和權(quán)限控制: 內(nèi)核調(diào)用通常不提供像系統(tǒng)調(diào)用那樣的安全性和權(quán)限控制層。用戶程序可以更自由地調(diào)用內(nèi)核的功能,但這也使得它們更容易破壞系統(tǒng)穩(wěn)定性。
-
通常用于開發(fā)操作系統(tǒng)或內(nèi)核模塊: 內(nèi)核調(diào)用通常被用于開發(fā)操作系統(tǒng)內(nèi)核本身或內(nèi)核模塊。它們不是一般用戶程序的主要接口。
總結(jié):系統(tǒng)調(diào)用是用戶空間程序與內(nèi)核之間的標(biāo)準(zhǔn)接口,提供了高級(jí)別的、安全的方式來(lái)訪問(wèn)內(nèi)核功能,而內(nèi)核調(diào)用更低級(jí)別,通常用于開發(fā)操作系統(tǒng)或內(nèi)核模塊,直接調(diào)用內(nèi)核功能,但需要更謹(jǐn)慎的處理。用戶程序在編寫時(shí)通常使用系統(tǒng)調(diào)用,而操作系統(tǒng)內(nèi)核的開發(fā)者可能需要使用內(nèi)核調(diào)用來(lái)開發(fā)操作系統(tǒng)本身的部分。
2.2 C語(yǔ)言庫(kù)函數(shù)
系統(tǒng)調(diào)用、庫(kù)函數(shù)和內(nèi)核調(diào)用之間存在密切的關(guān)系,它們共同構(gòu)成了操作系統(tǒng)和用戶程序之間的接口和交互方式:
系統(tǒng)調(diào)用與庫(kù)函數(shù)的關(guān)系:
- 系統(tǒng)調(diào)用是操作系統(tǒng)提供給用戶程序的接口之一,它允許用戶程序請(qǐng)求操作系統(tǒng)執(zhí)行特權(quán)級(jí)別的任務(wù),如文件操作、進(jìn)程管理、網(wǎng)絡(luò)通信等。
- 庫(kù)函數(shù)是在用戶空間中實(shí)現(xiàn)的高級(jí)別接口,它們通常封裝了系統(tǒng)調(diào)用,提供更方便、更抽象的方式來(lái)使用操作系統(tǒng)功能。庫(kù)函數(shù)通常包括對(duì)系統(tǒng)調(diào)用的封裝,以及其他一些常用功能的實(shí)現(xiàn)。例如,C語(yǔ)言的標(biāo)準(zhǔn)庫(kù)(libc)包含了許多庫(kù)函數(shù),它們實(shí)際上是建立在系統(tǒng)調(diào)用之上的。
- 用戶程序通常首先調(diào)用庫(kù)函數(shù),而庫(kù)函數(shù)可能在需要時(shí)調(diào)用系統(tǒng)調(diào)用來(lái)完成具體的操作。這種嵌套關(guān)系使得用戶程序可以更輕松地訪問(wèn)和使用操作系統(tǒng)功能,而不必直接與系統(tǒng)調(diào)用交互。
一般來(lái)說(shuō),用戶程序調(diào)用系統(tǒng)調(diào)用接口時(shí),會(huì)產(chǎn)生一個(gè)中斷或異常,處理器特權(quán)級(jí)別從用戶模式切換到內(nèi)核模式;一個(gè)系統(tǒng)調(diào)用對(duì)應(yīng)一個(gè)系統(tǒng)調(diào)用號(hào),內(nèi)核通過(guò)特定的號(hào)碼來(lái)調(diào)用相應(yīng)的服務(wù)例程。一些列操作完成后,內(nèi)核會(huì)將調(diào)用結(jié)果返回給用戶程序,特權(quán)模式也會(huì)切回到用戶模式。
三、Linux如何執(zhí)行一個(gè)程序
簡(jiǎn)要圖示:
運(yùn)行一個(gè)程序:
./ xxx
命令解析:首先,Shell會(huì)解析你輸入的命令。在這里,
./xxx
表示在當(dāng)前目錄下運(yùn)行名為xxx
的程序。程序查找:然后,Shell會(huì)在文件系統(tǒng)中查找你指定的程序。這里,它會(huì)在當(dāng)前目錄下查找名為
xxx
的文件。權(quán)限檢查:接著,Shell會(huì)檢查你是否有執(zhí)行該程序的權(quán)限。如果你沒有執(zhí)行權(quán)限,Shell將不會(huì)啟動(dòng)該程序。
創(chuàng)建進(jìn)程:如果你有執(zhí)行權(quán)限,Shell會(huì)通過(guò)調(diào)用
fork()
函數(shù)創(chuàng)建一個(gè)新的進(jìn)程來(lái)運(yùn)行該程序。加載和執(zhí)行:新創(chuàng)建的進(jìn)程會(huì)加載程序的代碼和數(shù)據(jù)到內(nèi)存中,并開始執(zhí)行。如果程序是動(dòng)態(tài)鏈接的,那么在這個(gè)階段,動(dòng)態(tài)鏈接器(由程序頭中的PT_INTERP指定)也會(huì)被加載到內(nèi)存中,并負(fù)責(zé)處理如符號(hào)解析和重定位等任務(wù)。
執(zhí)行main()函數(shù):最后,新創(chuàng)建的進(jìn)程開始執(zhí)行程序的main函數(shù)。當(dāng)main函數(shù)返回時(shí),進(jìn)程結(jié)束,資源被操作系統(tǒng)回收。
其中,創(chuàng)建一個(gè)新進(jìn)程的過(guò)程主要涉及以下步驟:
-
調(diào)用fork()函數(shù):
fork()
函數(shù)會(huì)復(fù)制當(dāng)前進(jìn)程(稱為父進(jìn)程),創(chuàng)建一個(gè)新的進(jìn)程(稱為子進(jìn)程)。子進(jìn)程幾乎是父進(jìn)程(在這里指的是shell進(jìn)程)的完全復(fù)制,包括程序計(jì)數(shù)器、CPU寄存器、打開文件描述符、信號(hào)控制設(shè)置等。 -
分配PID:每個(gè)進(jìn)程在系統(tǒng)中都有一個(gè)唯一的進(jìn)程標(biāo)識(shí)符(PID)。新創(chuàng)建的子進(jìn)程會(huì)被分配一個(gè)新的PID。
-
復(fù)制父進(jìn)程的資源:子進(jìn)程會(huì)繼承父進(jìn)程的資源,如打開文件、掛起信號(hào)等。這些資源是被復(fù)制的,而不是共享的。也就是說(shuō),父子進(jìn)程并不共享這些資源。
-
返回PID:在父進(jìn)程中,
fork()
函數(shù)返回新創(chuàng)建子進(jìn)程的PID。在子進(jìn)程中,fork()
函數(shù)返回0。這樣,程序可以區(qū)分父進(jìn)程和子進(jìn)程。 -
執(zhí)行子進(jìn)程:如果調(diào)用
fork()
后緊接著調(diào)用exec()
函數(shù),子進(jìn)程就會(huì)替換成一個(gè)全新的程序,開始執(zhí)行新程序的main函數(shù)。
在Linux中,一個(gè)進(jìn)程有8種方式可以終止:
正常終止有5種方式:
- 從
main
函數(shù)返回。 - 調(diào)用
exit
函數(shù)。 - 調(diào)用
_exit
或_Exit
函數(shù)。 - 最后一個(gè)線程從其啟動(dòng)例程返回。
- 最后一個(gè)線程調(diào)用
pthread_exit
。
異常終止有3種方式:
- 調(diào)用
abort
函數(shù)。 - 接收到一個(gè)信號(hào)并終止。
- 最后一個(gè)線程對(duì)取消請(qǐng)求做出響應(yīng)。
拓展說(shuō)明:
exit()函數(shù):
exit()
函數(shù)是C語(yǔ)言的標(biāo)準(zhǔn)庫(kù)函數(shù),定義在<stdlib.h>
頭文件中。這個(gè)函數(shù)用于立即終止調(diào)用進(jìn)程。任何屬于該進(jìn)程的打開的文件描述符都會(huì)被關(guān)閉,該進(jìn)程的子進(jìn)程由進(jìn)程1繼承。與return
不同,exit
是系統(tǒng)調(diào)用級(jí)別的,它表示了一個(gè)進(jìn)程的結(jié)束。
在C語(yǔ)言程序中,exit()
函數(shù)可以由任何需要終止程序的函數(shù)調(diào)用:
-
在
main
函數(shù)中:當(dāng)main
函數(shù)執(zhí)行完畢并準(zhǔn)備返回時(shí),會(huì)隱式地調(diào)用exit()
函數(shù)。 -
在其他函數(shù)中:如果在主函數(shù)
main()
或WinMain()
之外的其他函數(shù)體內(nèi)需要退出程序,也可以調(diào)用exit()
函數(shù)。 -
錯(cuò)誤處理:當(dāng)程序遇到無(wú)法處理的錯(cuò)誤情況時(shí),可能會(huì)調(diào)用
exit()
來(lái)立即終止程序。
_exit 和 _Exit :
-
_exit()
函數(shù)是在<unistd.h>
頭文件中定義的。它是POSIX.1標(biāo)準(zhǔn)的一部分,因此在POSIX兼容的系統(tǒng)(如Linux)上可用。 -
_Exit()
函數(shù)是在<stdlib.h>
頭文件中定義的。它是ISO C99標(biāo)準(zhǔn)的一部分,因此在支持C99或更高版本的系統(tǒng)上可用。 -
這兩個(gè)函數(shù)都用于立即終止程序,不執(zhí)行任何清理操作或刷新緩沖區(qū)。
abort函數(shù):
abort()
函數(shù)是C語(yǔ)言的一個(gè)標(biāo)準(zhǔn)庫(kù)函數(shù),定義在<stdlib.h>
頭文件中。這個(gè)函數(shù)的功能是以非正常的方式終止當(dāng)前執(zhí)行的程序。它不接受任何參數(shù),也沒有返回值。
與exit()
函數(shù)不同,abort()
函數(shù)會(huì)使程序立即終止,不會(huì)進(jìn)行常規(guī)的清理工作,比如清理堆棧、釋放內(nèi)存等。當(dāng)程序遇到無(wú)法恢復(fù)的錯(cuò)誤條件時(shí),可以調(diào)用abort()
函數(shù)來(lái)立即終止程序。
以下是一個(gè)使用abort()
函數(shù)的示例代碼:
#include <stdio.h>
#include <stdlib.h>
int main() {
int value = 0;
printf("Enter an integer greater than zero: ");
scanf("%d", &value);
if (value <= 0) {
fprintf(stderr, "Invalid input. Program will terminate.\n");
abort();
}
printf("You entered: %d\n", value);
return 0;
}
在上述示例中,如果用戶輸入小于或等于零的整數(shù),程序?qū)⒋蛴∫粭l錯(cuò)誤消息并調(diào)用abort()
函數(shù)來(lái)終止程序2。希望這個(gè)答案對(duì)你有所幫助!
程序異常退出的問(wèn)題: 不做清理和不刷新緩沖區(qū)
-
數(shù)據(jù)丟失:如果緩沖區(qū)中的數(shù)據(jù)沒有被寫入到文件或設(shè)備中,那么這些數(shù)據(jù)可能會(huì)丟失。例如,如果你的程序在崩潰時(shí)沒有刷新緩沖區(qū),那么緩沖區(qū)中的數(shù)據(jù)將無(wú)法輸出。
-
資源泄露:如果程序在終止時(shí)沒有進(jìn)行適當(dāng)?shù)那謇砉ぷ?,可能?huì)導(dǎo)致資源泄露。例如,如果你的程序打開了一個(gè)文件但沒有關(guān)閉它,那么這個(gè)文件描述符就會(huì)一直被占用,直到系統(tǒng)重啟。
-
性能下降:不刷新緩沖區(qū)可能會(huì)影響程序的性能。例如,如果緩沖區(qū)滿了但沒有被刷新,那么程序可能需要等待直到有足夠的空間來(lái)存儲(chǔ)新的數(shù)據(jù)。
-
數(shù)據(jù)混亂:不刷新緩沖區(qū)可能會(huì)導(dǎo)致數(shù)據(jù)混亂。比如,發(fā)一個(gè)數(shù)據(jù),666,還沒有被讀,又發(fā)一個(gè)數(shù)據(jù),999,這時(shí)如果再讀,就是666999了。
常見的例子是:端口被占用。
進(jìn)程1:
在Unix和類Unix系統(tǒng)(如Linux)中,進(jìn)程1通常是init進(jìn)程(systemd)。init進(jìn)程是系統(tǒng)啟動(dòng)后的第一個(gè)進(jìn)程,由內(nèi)核自動(dòng)啟動(dòng)。它在系統(tǒng)啟動(dòng)后執(zhí)行許多重要的任務(wù),包括:
-
初始化系統(tǒng):init進(jìn)程負(fù)責(zé)啟動(dòng)和配置系統(tǒng)的各個(gè)部分。
-
創(chuàng)建其他進(jìn)程:init進(jìn)程可以啟動(dòng)其他的系統(tǒng)進(jìn)程。
-
收養(yǎng)孤兒進(jìn)程:當(dāng)一個(gè)父進(jìn)程結(jié)束,而它的子進(jìn)程還在運(yùn)行,這些子進(jìn)程就成為了“孤兒”進(jìn)程。這些孤兒進(jìn)程將被init進(jìn)程“收養(yǎng)”,也就是說(shuō),它們的父進(jìn)程將變?yōu)閕nit。
-
系統(tǒng)關(guān)機(jī)或重啟:當(dāng)你想要關(guān)機(jī)或重啟系統(tǒng)時(shí),這個(gè)請(qǐng)求會(huì)被發(fā)送給init進(jìn)程,由它來(lái)完成關(guān)機(jī)或重啟的操作。文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-718429.html
文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-718429.html
到了這里,關(guān)于【Linux C】Linux如何執(zhí)行一個(gè)程序(程序存儲(chǔ)空間、系統(tǒng)調(diào)用、內(nèi)核調(diào)用)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!