Linux环境编程--linux中的perror、exit、_exit、wait 和 waitpid
#include<stdio.h>
?????? #include<stdlib.h>
定義函數
void perror(const char *s);? perror ("open_port");函數說明
perror ( )用 來 將 上 一 個 函 數 發 生 錯 誤 的 原 因 輸 出 到 標 準 錯誤 (stderr) 。參數 s 所指的字符串會先打印出,后面再加上錯誤原因字符串。此錯誤原因依照全局變量error 的值來決定要輸出的字符串。?????? 在庫函數中有個error變量,每個error值對應著以字符串表示的錯誤類型。當你調用"某些"函數出錯時,該函數已經重新設置了error的值。perror函數只是將你輸入的一些信息和現在的error所對應的錯誤一起輸出。
exit:(#include <stdlib.h>)
??? 在C語言的main函數中我們通常使用return (0);這樣的方式返回一個值。但這是限定在非void情況下的,也就是非void main()這樣的形式。 ??? exit()通常是用在子程序中用來終結程序用的,使用后程序自動結束,跳出操作系統。
??? exit(0) 表示程序正常退出,
??? exit(1)/exit(-1)表示程序異常退出。
exit() 結束當前進程/當前程序/,在整個程序中,只要調用 exit ,就結束。
但在如果把exit用在main內的時候無論main是否定義成void返回的值都是有效的,并且exit不需要考慮類型,exit(1)等價于return (1) 。
例如:
#include<stdlib.h>
int main()
{
? exit (1);//等價于return (1);
}
exit()是一個函數 ,結束一個進程,它將刪除進程使用的內存空間,同時把錯誤信息返回父進程,在父進程中wait系統調用將接受到此返回信息。
進程就好比人一樣有其生命,我們通過fork()函數來創建一個進程,那么我們又是如何來中止進程呢。
進程退出
1.在Linux中任何讓一個進程退出
進程退出表示進程即將結束。在Linux中進程退出分為了正常退出和異常退出兩種。
1>正常退出
a. 在main()函數中執行return 。
| ? |
b.調用exit()函數?? #include <stdlib.h>??? void exit(int status)
c.調用_exit()函數?? #include <unistd.h>?? void _exit(int status)
status 是一個整型的參數,可以利用這個參數傳遞進程結束時的狀態。一般來說,
0 表示正常結束;其他的數值表示出現了錯誤,進程非正常結束。
在實際編程時,可以用 wait 系統調用接收子進程的返回值,從而針對不同的情況
進行不同的處理
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 }
函數經過調試后
$ gcc exit.c -o 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 }
? 函數經過調試后
$ gcc _exit.c -o _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看運行結果是什么,為什么會產生這樣的結果呢?)
小知識
在一個進程調用了 exit 之后,該進程并不馬上就完全消失,而是留下一個稱為僵尸進程wait
(Zombie)的數據結構。僵尸進程是一種非常特殊的進程,它幾乎已經放棄了所有內存空間,
沒有任何可執行代碼,也不能被調度,僅僅在進程列表中保留一個位置,記載該進程的退出
狀態等信息供其他進程收集,除此之外,僵尸進程不再占有任何內存空間。
????? wait 函數是用于使父進程(也就是調用 wait 的進程) 阻塞,直到一個子進程結束或者該進程接到了一個指定的信號為止。
如果該父進程沒有子進程或者他的子進程已經結束, wait則就會立即返回。
#include <sys/types.h>
#include <sys/wait.h>
pid_t wait(int *status)
waitpid
????? waitpid 的作用和 wait 一樣,但它并不一定要等待第一個終止的子進程,它還有若干選項,如可提供一個非阻塞版本的 wait 功能,也能支持作業控制。實際上 wait 函數只是 waitpid 函數的一個特例,在 Linux 內部實現 wait 函數時直接調用的就是 waitpid 函數。
#include <sys/types.h>
#include <sys/wait.h>
pid_t waitpid(pid_t pid, int *status, int options)
總結
以上是生活随笔為你收集整理的Linux环境编程--linux中的perror、exit、_exit、wait 和 waitpid的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 好听的同学群名字大全
- 下一篇: 黄精多少钱啊?