Unix出錯處理
當UNIX系統的函數出錯時,通常會返回一個負值。我們判斷函數的返回值小於0表示出錯了,注意我們並不知道為什麼出錯。例如我們open一個文件,返回值-1表示打開失敗,但是為什麼打開失敗呢?
原來UNIX維護一個全局變量errno,error通常被設定成具有特定信息的值。回到之前如果文件打開失敗,此時讀取errno的值為EACCES,表示產生了權限問題。ok此時我們只要檢查文件的權限問題。
errno錯誤代碼類型可以通errno的數據手冊查詢。輸入 man errno
特別是在網絡編程中。如果你沒有用過errno,那隻能說明你的程序不夠健壯。文件<errno.h>中定義了符合errno以及可以賦予它的各種常量,這些常量都以字符E開頭。
POSIX和ISO C將errno定義為這樣一個符號,它擴展成為一個可修改的整型左值(lvalue)。這可以是包含出錯編號的一個整數,或者是一個返回出錯編號指針的函數。以前使用的定義是:
extern int error;
但是在支持線程的環境中,多個線程共享進程地址空間,每個線程都有屬於它自己的局部extern以避免一個線程干擾另一個線程。例如,Linux支持多線程存取errno,將其定義為:
extern int *__errno_location(void); #define errno (*__errno_locatioin)
C標準定義了兩個函數,它們幫助打印出錯信息:
#include <string.h> char *strerror(int errnum); 返回值:指向消息字符串的指針
此函數將errnum(它通常是errno的值)映射為一個出錯信息字符串,並且返回此字符串的指針。
perror函數基於errno的當前值,在標準出錯上產生一條出錯消息,然後返回。
#include <stdio.h> void perror(const char *msg);
它首先輸出由msg指向的字符串,然後是一個冒號,一個空格,接著是對應於errno值的出錯信息,最後是一個換行符。
下面我們用一些代碼測試一下
#include <stdio.h> #include <unistd.h> #include <errno.h> #include <string.h> #include <fcntl.h> int main(int argc,char *argv[]) { int fd; char *errmesg; // test strerror fd = open(argv[1],O_RDWR);// open with write and read errmesg = strerror(errno); printf("%s\n",errmesg); // test perror fd = open(argv[2],O_RDWR);// open with write and read perror("result is"); return 0; }
我們先查看home目錄下
測試結果如下
errno的錯誤類型分為致命和非致命的,對於致命的錯誤一般打印一條消息或者採用syslog方式存儲的日誌然後退出。對於一些非致命出錯,包括EAGIN、ENOBUFS、ENOLCK、等。
常見情況網路編程一般忽略EINIT的中斷錯誤,
EBUSY表面資源正在被佔用。
用戶表標識
1、用戶id,cat/etc/passwd。用戶id就是口令登錄時用戶id,其中0標識超級用戶,都是管理員在確定一個用戶登錄名的同時確定用戶id,用戶不能修改
2、組id,都是管理員在確定一個用戶登錄名的時分配。目的讓一些不同的用戶id的具有相同的組id。這種機制允許同組的各個成員之間共享資源。
組名映射在/etc/group
3、附屬id
可以通過getuid函數獲得用戶id,可以通過getgid獲得組id
信號
信號singal,用於通知進程發生某種情況。例如,如某一進程執行除法操作,其除數為0,內核會把SIGFPE(浮點異常)的信號發給該進程。進程有一下3中處理信號的方式
1.忽略信號 風險比較大
2.按照系統默認的方式處理,對於浮點異常系統默認關閉進程
3.提供一個函數,信號發生後調用該函數,這被稱為捕捉信號,如何異步IO通信
時間值
unix系統使用2中不同時間值
1、日曆時間。該值是自協調時間值UTC,1970年1月1日00:00:00至現在所經歷的秒數。這個時間可以保存文件最後一次修改的時間
系統基本的數據類型time_t
2、進程時間。也稱CPU時間。一般度量進程的執行時間,分成3個進程時間
- 時鐘時間
- 用戶CPU時間
- 系統CPU時間
時鐘時間又稱牆上時間,它是進程運行時間的綜合。其中與系統運行的進程數有關
用戶CPU時間指的用戶指令花費的時間,系統cpu時間指的是內核程序所經歷的時間,
用戶時間+系統時間 = 該進程的運行的總時間 <= 時鐘時間
獲取的方式輸入
time -p 程序
real 時鐘時間
user 用戶CPU時間
sys 系統cpu時間
由於指令很短是毫秒級或者微秒級的時間 time顯示精度不夠,所以顯示0
2017/4/2(堅持2天一個博客 連載unix的環境編程)