九色91_成人精品一区二区三区中文字幕_国产精品久久久久一区二区三区_欧美精品久久_国产精品99久久久久久久vr_www.国产视频

Hello! 歡迎來到小浪云!


【Linux系統編程】—— 深度解析進程等待與終止:系統高效運行的關鍵


avatar
小浪云 2025-04-17 20

重新認識fork()函數在linux系統編程中的應用

初識fork()函數:在Linux中,fork()函數是一個非常重要的系統調用,它用于從一個已存在的進程中創建一個新的進程。新創建的進程被稱為子進程,而原進程則被稱為父進程。

#include <unistd.h> pid_t fork(void); 返回值:子進程中返回0,父進程返回子進程的ID,錯誤時返回-1

當一個進程調用fork()函數時,控制權轉移到內核中的fork代碼。內核執行以下操作:

  • 為子進程分配新的內存塊和內核數據結構
  • 將父進程的部分數據結構內容復制到子進程
  • 將子進程添加到系統進程列表中
  • fork()函數返回,調度器開始調度

【Linux系統編程】—— 深度解析進程等待與終止:系統高效運行的關鍵【Linux系統編程】—— 深度解析進程等待與終止:系統高效運行的關鍵 可以看到,這里的例子創建了一個進程,PID為3109,這就是子進程。

【Linux系統編程】—— 深度解析進程等待與終止:系統高效運行的關鍵 當一個進程調用fork()函數后,會產生兩個具有相同二進制代碼的進程,且它們都運行到相同的點。但每個進程可以開始它們自己的執行路徑,如下面的程序所示。

int main(void) {     pid_t pid;     printf("Before: pid is %dn", getpid());     if ((pid=fork()) == -1)         perror("fork()"),exit(1);     printf("After: pid is %d, fork return %dn", getpid(), pid);     sleep(1);     return 0; }

運行結果:

[root@localhost Linux]# ./a.out Before: pid is 43676 After: pid is 43676, fork return 43677 After: pid is 43677, fork return 0

這里可以看到三行輸出,一行是Before,兩行是After。進程43676先打印Before消息,然后它打印了After。另一個After消息是由進程43677打印的。注意,進程43677沒有打印Before,為什么呢?如下圖所示:

【Linux系統編程】—— 深度解析進程等待與終止:系統高效運行的關鍵 因此,在fork之前,父進程獨立執行;在fork之后,父子兩個執行流分別執行。注意,fork之后,誰先執行完全由調度器決定。

fork()函數的返回值:子進程返回0,父進程返回子進程的PID。

寫時拷貝(copy-on-write, COW)是計算機系統中廣泛應用的一種優化技術,尤其是在操作系統虛擬化和內存管理領域。其主要目的是節省內存資源和提高效率。

工作原理:寫時拷貝的基本思想是,當多個進程共享相同的資源(例如內存或文件)時,如果一個進程對這些資源進行修改,系統并不會立即為該進程創建資源的副本,而是推遲到該進程真正進行修改時,才為它分配一個新的副本。具體步驟如下:

  • 共享資源:多個進程最初可以共享同一塊內存區域或文件(即資源是只讀的)。
  • 標記只讀:系統會將這些共享的資源標記為只讀。
  • 修改時拷貝:當一個進程嘗試修改共享資源時,操作系統會為該進程創建資源的副本,并將其設為可寫。其他進程仍然使用原始資源,而修改的進程則使用新的副本。
  • 繼續共享:如果其他進程繼續只讀訪問原始資源,不會進行拷貝,節省內存和計算資源。

具體的理解可以看下面這一張圖片:

【Linux系統編程】—— 深度解析進程等待與終止:系統高效運行的關鍵

優點:

  • 節省內存:由于多個進程或線程可以共享同一資源副本,減少了內存的消耗。
  • 提高性能:避免不必要的拷貝操作,只有在修改資源時才進行拷貝,從而提高了效率。
  • 提高數據一致性:寫時拷貝確保在修改數據時不會影響其他進程或線程讀取到的數據,避免了數據沖突。

缺點:

  • 延遲開銷:在第一次修改資源時,系統需要創建資源的副本,這可能帶來一定的性能開銷。
  • 資源消耗:如果多個進程頻繁進行寫操作,系統會進行多次資源拷貝,可能增加資源消耗。

fork的常規用法以及調用失敗的原因:一個父進程希望復制自己,使父子進程同時執行不同的代碼段。例如,父進程等待客戶端請求,生成子進程來處理請求。一個進程要執行一個不同的程序。例如子進程從fork返回后,調用exec函數。

原因:

  • 系統中有太多的進程
  • 實際用戶的進程數超過了限制
  • 進程終止

進程終止的本質是釋放系統資源,就是釋放進程申請的相關內核數據結構和對應的數據和代碼。

進程終止對應的三種情況:

  • 代碼運行完畢,結果正確
  • 代碼運行完畢,結果不正確
  • 代碼異常終止

進程常見的退出方法:

正常終止(可以通過 echo $? 查看進程退出碼):

  • 從main返回
  • 調用exit

_exit

異常退出:

  • ctrl + c,信號終止

退出碼(退出狀態)可以告訴我們最后一次執行的命令的狀態。在命令結束以后,我們可以知道命令是成功完成的還是以錯誤結束的。其基本思想是,程序返回退出代碼 0 時表示執行成功,沒有問題。

代碼 1 或 0 以外的任何代碼都被視為不成功。

下面是Linux shell常見的退出碼:

【Linux系統編程】—— 深度解析進程等待與終止:系統高效運行的關鍵

_exit函數:

#include <unistd.h> void _exit(int status); 參數:status 定義了進程的終止狀態,父進程通過wait來獲取該值

說明:雖然status是int,但是僅有低8位可以被父進程所用。所以_exit(-1)時,在終端執行$?發現返回值是255。

exit函數:

#include <unistd.h> void exit(int status);

exit最后也會調用_exit, 但在調用_exit之前,還做了其他工作:

  • 執行用戶通過 atexit或on_exit定義的清理函數。
  • 關閉所有打開的流,所有的緩存數據均被寫入
  • 調用_exit

【Linux系統編程】—— 深度解析進程等待與終止:系統高效運行的關鍵

示例:

int main() {     printf("hello");     exit(0); } <p>int main() { printf("hello"); _exit(0); }

上面的結果分別為:

運行結果: [root@localhost linux]# ./a.out hello [root@localhost linux]#</p><p>運行結果: [root@localhost linux]# ./a.out [root@localhost linux]#

return退出:return是一種更常見的退出進程方法。執行return n等同于執行exit(n),因為調用main的運行時函數會將main的返回值作為exit的參數。

進程等待:進程等待是指在操作系統中,當一個進程無法繼續執行時,它進入一種阻塞狀態,等待某些條件或事件的發生才能恢復執行。等待通常發生在進程需要等待資源(如CPU、內存、I/O設備等)或與其他進程之間的同步和通信。

進程等待的必要性:

  • 資源共享與避免沖突:多個進程共享資源時,等待機制確保不會發生沖突,避免競爭條件。
  • 進程同步與通信:確保進程按照正確順序執行,例如生產者和消費者模型。
  • CPU資源管理:避免無謂的CPU占用,讓等待的進程釋放CPU,提高系統效率。
  • 防止死鎖:通過合理設計等待策略,避免多個進程互相等待,進入死鎖狀態。
  • 提升并發性:使系統能夠并發執行多個進程,最大化資源利用。
  • 提高系統穩定性:管理進程優先級,保證重要任務及時執行,確保系統穩定運行。

進程等待的方法:

wait方法:

#include <sys></p><h1>include <sys></h1><p>pid_t wait(int<em> status); 返回值:成功返回被等待進程的PID,失敗返回-1。 參數:輸出型參數,獲取子進程退出狀態,不關心則可以設置成為NULL

waitpid方法:

pid_t waitpid(pid_t pid, int </em>status, int options); 返回值:當正常返回的時候waitpid返回收集到的子進程的進程ID;如果設置了選項WNOHANG,而調用中waitpid發現沒有已退出的子進程可收集,則返回0;如果調用中出錯,則返回-1,這時errno會被設置成相應的值以指示錯誤所在; 參數:pid:Pid=-1,等待任意一個子進程。與wait等效。Pid>0.等待其進程ID與pid相等的子進程。 status: 輸出型參數 WIFEXITED(status): 若為正常終止子進程返回的狀態,則為真。(查看進程是否是正常退出) WEXITSTATUS(status): 若WIFEXITED非零,提取子進程退出碼。(查看進程的退出碼) options:默認為0,表示阻塞等待。WNOHANG: 若pid指定的子進程沒有結束,則waitpid()函數返回0,不予以等待。若正常結束,則返回該子進程的ID。

如果子進程已經退出,調用wait/waitpid時,wait/waitpid會立即返回,并且釋放資源,獲得子進程退出信息。如果在任意時刻調用wait/waitpid,子進程存在且正常運行,則進程可能阻塞。如果不存在該子進程,則立即出錯返回。

【Linux系統編程】—— 深度解析進程等待與終止:系統高效運行的關鍵

獲取子進程的status:wait和waitpid都有status參數,該參數是一個輸出型參數,由操作系統填充。如果傳遞NULL,表示不關心子進程的退出狀態信息。否則,操作系統會根據該參數,將子進程的退出信息反饋給父進程。status不能簡單的當作整形來看待,可以當作位圖來看待,具體細節如下圖(只研究status低16位):

【Linux系統編程】—— 深度解析進程等待與終止:系統高效運行的關鍵

進程的阻塞等待方式:

int main() { pid_t pid; pid = fork(); if(pid < 0) { perror("fork"); exit(1); } else if(pid == 0) { printf("子進程運行中,PID=%dn", getpid()); sleep(5); exit(0); } else { printf("父進程等待子進程...n"); wait(NULL); printf("子進程已終止,父進程繼續...n"); } return 0; }

進程的非阻塞等待方式:

#include <stdio.h></p><h1>include <stdlib.h></h1><h1>include <sys></h1><h1>include <unistd.h></h1><h1>include <vector></h1><p>typedef void (*handler_t)(); // 函數指針類型 std::vector<handler_t> handlers; // 函數指針數組</p><p>void fun_one() { printf("這是一個臨時任務1n"); }</p><p>void fun_two() { printf("這是一個臨時任務2n"); }</p><p>void Load() { handlers.push_back(fun_one); handlers.push_back(fun_two); }</p><p>void handler() { if (handlers.empty()) Load(); for (auto iter : handlers) iter(); }</p><p>int main() { pid_t pid; pid = fork(); if (pid < 0) { perror("fork"); exit(1); } else if (pid == 0) { printf("子進程運行中,PID=%dn", getpid()); sleep(5); exit(0); } else { printf("父進程非阻塞等待子進程...n"); int status; while (waitpid(pid, &status, WNOHANG) == 0) { printf("父進程繼續執行...n"); sleep(1); handler(); } if (WIFEXITED(status)) { printf("子進程正常終止,退出碼=%dn", WEXITSTATUS(status)); } else { printf("子進程異常終止n"); } } return 0; }

相關閱讀

主站蜘蛛池模板: 中文字幕国产 | 国产成人久久精品一区二区三区 | 亚洲女人的天堂 | 欧美精品久久久久 | 国产精品视频久久 | 国产高清在线视频 | av黄色在线观看 | 日韩毛片 | 日韩一区二区三区在线视频 | 日韩成人在线一区 | 国产精品入口麻豆www | 特黄一级 | 男人天堂网址 | 二区久久 | 欧美aaaaaaaa | 国内精品久久精品 | 成人精品国产一区二区4080 | 欧美亚洲国产一区二区三区 | 欧美一a一片一级一片 | 在线观看中文字幕av | 午夜视频在线免费观看 | 国产欧美一区二区三区在线看 | 免费国产一区二区 | 国产精品高 | 国产高清在线观看 | 九九久久免费视频 | 97日日碰人人模人人澡分享吧 | 亚洲精品乱码久久久久久蜜桃 | 中文在线а√在线8 | 成年人免费网站 | 狠狠狠色丁香婷婷综合久久五月 | 色婷婷综合久久久中字幕精品久久 | 精品一区二区av | 久久精品美女 | 97国产一区二区精品久久呦 | 久久久久久国模大尺度人体 | 日韩精品999| 久久国产婷婷国产香蕉 | 九九热免费在线观看 | 日韩美女一区二区三区在线观看 | 久久国产精品视频 |