Linux進程學習四

來源:互聯網
上載者:User

exit()和_exit()函數

進程就好比人一樣有其生命,我們通過fork()函數來建立一個進程,那麼我們又是如何來中止進程呢。

進程退出

1.在Linux中任何讓一個進程退出

進程退出表示進程即將結束。在Linux中進程退出分為了正常退出和異常退出兩種。

1>正常退出

a. 在main()函數中執行return 。

b.調用exit()函數

c.調用_exit()函數

2>異常退出

a.調用about函數

b.進程收到某個訊號,而該訊號使程式終止。

Tiger-John說明:
不管是那種退出方式,系統最終都會執行核心中的同一代碼。這段代碼用來關閉進程所用已開啟的檔案描述符,釋放它所佔用的記憶體和其他資源。

 

 

3>比較以上幾種退出方式的不同點

(1)exit和return 的區別:

a.exit是一個函數,有參數。exit執行完後把控制權交給系統

b.return是函數執行完後的返回。renturn執行完後把控制權交給調用函數。

(2)exit和abort的區別:

a.exit是正常終止進程

b.about是異常終止。


現在我們重點瞭解exit()和_exit()函數

 

2.exit()和_exit()的學習

1>exit和_exit函數都是用來終止進程的。

當程式執行到exit或_exit時,系統無條件的停止剩下所有操作,清除包括PCB在內的各種資料結構,並終止本進程的運行。

2>exit在標頭檔stdlib.h中聲明,而_exit()聲明在標頭檔unistd.h中聲明。exit中的參數exit_code為0代表進程正常終止,若為其他值表示程式執行過程中有錯誤發生。

3>exit()和_exit()的區別:

a._exit()執行後立即返回給核心,而exit()要先執行一些清除操作,然後將控制權交給核心。

b.調用_exit函數時,其會關閉進程所有的檔案描述符,清理記憶體以及其他一些核心清理函數,但不會重新整理流(stdin, stdout, stderr  ...).   exit函數是在_exit函數之上的一個封裝,其會調用_exit,並在調用之前先重新整理流。

Tiger-John說明:

exit()函數與_exit()函數最大區別就在於exit()函數在調用exit系統之前要檢查檔案的開啟情況,把檔案緩衝區的內容寫迴文件。由於Linux的標準函數庫中,有一種被稱作“緩衝I/O”的操作,其特徵就是對應每一個開啟的檔案,在記憶體中都有一片緩衝區。每次讀檔案時,會連續的讀出若干條記錄,這樣在下次讀檔案時就可以直接從記憶體的緩衝區讀取;同樣,每次寫檔案的時候也僅僅是寫入記憶體的緩衝區,等滿足了一定的條件(如達到了一定數量或遇到特定字元等),再將緩衝區中的內容一次性寫入檔案。這種技術大大增加了檔案讀寫的速度,但也給編程代來了一點兒麻煩。比如有一些資料,認為已經寫入了檔案,實際上因為沒有滿足特定的條件,它們還只是儲存在緩衝區內,這時用_exit()函數直接將進程關閉,緩衝區的資料就會丟失。因此,要想保證資料的完整性,就一定要使用exit()函數。

 

 

c . 通過一個函數執行個體來看看它們之間的區別:

函數執行個體1 : exit.c

 1 #include<stdio.h>
 2 #include<stdlib.h>
 3
 4 int main()
 5 {
 6         printf("using exit----/n");
 7         printf("This is the content in buffer/n");
 8         exit(0);
9 }

函數經過調試後

think@ubuntu:~/work/process_thread/exit$ gcc exit.c -o exit
think@ubuntu:~/work/process_thread/exit$ ./exit

執行結果為:

using exit----
This is the content in buffer

函數執行個體2:_exit.c

 1 #include<stdio.h>
 2 #include<unistd.h>
 3
 4 int main(void)
 5 {
 6         printf("using _exit--/n");
 7         printf("This is the content in buffer");
 8         _exit(0);
 9 }
 函數經過調試後

think@ubuntu:~/work/process_thread/exit$ gcc _exit.c -o _exit
think@ubuntu:~/work/process_thread/exit$ ./_exit

執行結果為:

using _exit--

 

Tiger-John說明:

1.printf函數就是使用緩衝I/O的方式,該函數在遇到“/n”分行符號時自動的從緩衝區中將記錄讀出。所以exit()將緩衝區的資料寫完後才退出,而_exit()函數直接退出。

2.大家也可以把函數執行個體2中的printf("This is the content in buffer");改為printf("This is the content in buffer/n")(即在printf中最後加一個/n看運行結果是什麼,為什麼會產生這樣的結果呢?)

 

 

Tiger-John補充:

父子進程終止的先後順序不同會產生不同的結果。

1>父進程先於子進程終止:

此種情況就是我們前面所用的孤兒進程。當父進程先退出時,系統會讓init進程接管子進程。

2>子進程先於父進程終止,而父進程又沒有調用wait函數

此種情況子進程進入僵死狀態,並且會一直保持下去直到系統重啟。子進程處於僵死狀態時,核心只儲存進程的一些必要資訊以備父進程所需。此時子進程始終佔有著資源,同時也減少了系統可以建立的最大進程數。

 

什麼是僵死狀態呢?

 

一個已經終止、但是其父進程尚未對其進行善後處理(擷取終止子進程的有關資訊,釋放它仍佔有的資源)的進程被稱為僵死進程(zombie)。ps命令將僵死進程的狀態列印為Z

3>子進程先於父進程終止,而父進程調用了wait函數

此時父進程會等待子進程結束。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.