第一章 UNIX基礎知識
1.2UNIX體系結構
UNIX體系結構如下圖,系統內核接口被稱爲系統調用,公用函數庫構建在系統調用接口之上,應用軟件可以使用公用函數庫,也可以使用系統調用。shell是一個特殊的應用程序,它爲運行其他應用程序提供了一個接口。
1.3登錄
1.登錄名
用戶輸入登錄名及口令之後,系統在/etc/passwd文件中查看登錄名,口令文件中的登錄項是由7個以冒號分隔的字段組成,它們是:登錄名、加密口令、數值用戶ID(205)、數值組ID(105)、註釋字段、起始目錄(/home/sar)以及shell程序(/bin/ksh)。
目前所有新系統的加密口令已轉移到另一個文件中。
2.shell
shell是一個命令解釋器,它讀取用戶輸入,然後招待命令。用戶可以通過兩種方式向shell輸入:1、常用終端(交互式shell,比如我們在redhat linux9 裏點擊左下角那個大圖標,開啓的一個終端),2、文件(也被稱爲腳本,可以在腳本中預先編輯輸入一系列shell命令,完成特定工作,類似於windows中的批處理文件)。
1.4文件和目錄
1.文件系統
UNIX文件系統是目錄和文件組成的一種層次結構,目錄起點稱爲根(root),其名字是一個字符/。目錄是一個包含許多目錄項的文件,在邏輯上可以認爲每個目錄項都包含一個文件名,同時還包含說明該文件屬性(文件類型、文件大小、文件所以有者、文件權限、最後修改時間……可以用stat和fstat函數查看這些屬性,它們返回的是包含所有文件屬性的一個信息結構)的信息。
第五章 標準I/O庫。
2.文件名
l 不能出現在文件名中的字符只有兩個:/和空操作符null。
l 創建新目錄時會自動他那兩個文件名: . 和 .. 分別指當前目錄和父目錄。最高層次中二者相同。
3.路徑名
l 沒有什麼特別的,記住路徑名分爲絕對路徑名和相對路徑名就行了。
4.工作目錄
l 每個進程都有一個工作目錄,有時稱其爲當前工作目錄,所有相對路徑名都從工作目錄開始解釋
5.起始目錄
l 登錄時,工作目錄設置爲起始目錄
1.5輸入和輸出
1.文件描述符
通常是一個小的非負整數,內核用它標識一個特定進程正在訪問的文件。內核打開或創建一個新文件時,它返回一個文件描述臺灣省,讀、寫文件時都會用到它。
2.標準輸入、輸出和出錯
按慣例,每運行一個新程序時,所有shell都爲其打開三個描述符:標準輸入、輸出和出錯。若沒有做特殊處理,則三個描述符都鏈向終端。當然大多數shell都提供一種方法,使其中任何一個或所以有這三個描述符都能重新定向到某個文件,如:
ls > file.list
則標準輸出重定向到file.list文件上。
3.不帶緩衝的I/O
函數open read write lseek close提供了不帶緩衝的I/O,這使得輸入和輸出可以及時到達。
4.標準I/O(帶緩衝的I/O)
使用標準I/O函數可以無需擔心如何選取最佳的緩衝區大小 ,因爲庫函數已經幫我們設置好了。它的另一個優點是簡化了對輸入行的處理,如標準I/O函數fgets函數讀一完整的行,而不帶緩衝的I/O函數read則讀指定的字節數。
1.6程序和進程
1.程序
指存放於磁盤上、牌某個目錄中的一個可招待文件,使用6個exec函數中的任意一個,將程序讀入存儲器,並使其執行。
2.進程和進程ID
程序執行實例被稱爲進程,每一個進程都擁有一個唯一的數字標識符,稱爲進程ID,進程ID一非負整數。
3.進程控制
用於控制進程的函數主要有三個:fork(創建一個新進程)、exec(執行程序)、waitpid(暫時停止目前進程的執行,直到有信號來到或子進程結束)。
4.線程和線程ID
通常,一個進程擁有至少一個線程,在一個進程內的所以有線程共享同一地址空間、文件描述符、棧以及與進程相關的屬性。
與進程相同,純種也用ID標識,但是,線程ID只在它所屬進程內起作用。
控制線程的函數與控制進程的函數類似,但另有一套。
1.7出錯處理
1.獲得出錯信息
UNIX函數出錯時,通常返回一個負值。另外,還可以通過整型變量errno來獲得出錯信息。如對於open出錯時,有大約15種不同的errno值表示各種出錯信息(文件不存在,權限問題等)。
注:在多線程環境中,多個線程共享地址空間,每個線程都有屬於它自己的局部errno以免干擾另外一個線程。
errno有兩個應該知道的規則。第一、如果沒有出錯,則其值不會被一個例程清除;第二、任一函數都不會將errno設爲0,在<errno.h>中定義的所以有常量都不爲0。
2.出錯恢復
可將在<errno.h>中定義的各種出錯分成致命性的和非致命性兩類。對於致命性的錯誤,無法招待恢復動作,最多只能在用戶屏幕上打印一條出錯消息或寫入日誌中,然後程序終止;對於非致命性的出錯,本質上是暫時的,例如資源短缺,一般恢復動作是延遲一些時間再試。
另外,應用程序開發者可以決定他們的程序哪些程序出錯是可以恢復的。如果使用一種從錯誤中恢復的合理策略,那麼由於避免了應用程序的異常終止,就能改善應用程序的健壯性。
1.8用戶標識
包括用戶ID、組ID、附加組ID,略
1.9信號
是通知進程已發生某種情況的一種技術。進程處理信號有三種選擇:
1、 忽略該信號,由於一些異常產生的後果不確定,所以不推薦你不用這種方式
2、 按系統默認方式處理
3、 提供一個函數,信號發生時則調用該函數,這種方式被稱爲捕捉信號。
很多情況可以產生信號,可以用中斷鍵(interrupt key)和退出鍵(quit key),另外就是調用名爲kill的函數,在一個進程中調用此函數,就可以向另一個進程發送一個信號:當向一個進程發送信號時,我們必須是該進程的所以有者或超級用戶。
1.10時間值
UNIX使用兩種不同的時間值:日曆時間、進程時間
其中,進程時間分爲三種:
時鐘時間,又稱爲wall clock time,是進程運行的起止時間差。
用戶CPU時間,指執行用戶指令所用的時間
系統CPU時間,指爲該進程執行內核程序所經歷的時間
用戶/系統CPU時間這種常被稱爲CUP時間
1.21系統調用和庫函數
所有的操作系統都提供多種服務的入口點,程序由此高內核請求服務,UNIX所使用的技術是爲每個系統調用在標準C庫中設置一個具有同樣名字的函數。但庫函數和系統調用二者區別甚大:
1、 庫函數會調用一個或多個內核的系統調用,但它們並不是內核的入口點。
2、 庫函數和系統調用都以C函數的形式出現,但必要是我們可以替換庫函數,但不能替換系統調用。例如對於庫函數malloc我們如果不喜歡其操作方式,則可以定義自己的malloc函數。
3、 系統調用通常提供一種最小的接口,而庫函數通常提供比較複雜的功能。考慮UNIX下獲得當前時間,系統調用只會返回國際標準時間1970年1月1日零點以來所經過的秒數,但庫函數則可以利用這個信息轉換成多種我們需要的信息。
下圖可以較爲充分說明庫函數和系統調用的區別: