Time of Update: 2017-02-27
#include "apue.h" #include <errno.h> #include <limits.h> #ifdef PATH_MAX static int pathmax = PATH_MAX; #else static int pathmax = 0; #endif #define SUSV3 200112L static long posix_version = 0; /* If PATH_MAX is indeterminate,
Time of Update: 2017-02-27
處理序間通訊必須通過核心提供的通道,而且必須有一種辦法在進程中標識核心提供的某個通道,前面講過的匿名管道是用開啟的檔案描述符來標識的。如果要互相通訊的幾個進程沒有從公用祖先那裡繼承檔案描述符,它們怎麼通訊呢?核心提供一條通道不成問題,問題是如何標識這條通道才能使各進程都可以訪問它?檔案系統中的路徑名是全域的,各進程都可以訪問,因此可以用檔案系統中的路徑名來標識一個IPC通道。FIFO和UNIX Domain
Time of Update: 2017-02-27
一、當沒有資料可讀時O_NONBLOCK disable:read調用阻塞,即進程暫停執行,一直等到有資料來到為止。O_NONBLOCK enable:read調用返回-1,errno值為EAGAIN。樣本程式如下:/************************************************************************* > File Name: process_.c > Author: Simba > Mail: dameng34@1
Time of Update: 2017-02-27
一、處理序間通訊每個進程各自有不同的使用者地址空間,任何一個進程的全域變數在另一個進程中都看不到,所以進程之間要交換資料必須通過核心,在核心中開闢一塊緩衝區,進程1把資料從使用者空間拷到核心緩衝區,進程2再從核心緩衝區把資料讀走,核心提供的這種機制稱為處理序間通訊(IPC,InterProcess Communication)。如下圖所示。二、管道是一種最基本的IPC機制,由pipe函數建立:#include <unistd.h>int pipe(int
Time of Update: 2017-02-27
一、利用pause和alarm函數實現sleep函數#include <unistd.h>int pause(void);pause函數使調用進程掛起直到有訊號遞達。如果訊號的處理動作是終止進程,則進程終止,pause函數沒有機會返回;如果訊號的處理動作是忽略,則進程繼續處於掛起狀態,pause不返回;如果訊號的處理動作是捕捉,則調用了訊號處理函數之後pause返回-1,errno設定為EINTR,所以pause只有出錯的傳回值。錯誤碼EINTR表示“被訊號中斷”。
Time of Update: 2017-02-27
一、sigqueue函數功能:新的發送訊號系統調用,主要是針對即時訊號提出的支援訊號帶有參數,與函數sigaction()配合使用。原型:int sigqueue(pid_t pid, int sig, const union sigval value);參數:sigqueue的第一個參數是指定接收訊號的進程id,第二個參數確定即將發送的訊號,第三個參數是一個聯合資料結構union sigval,指定了訊號傳遞的參數,即通常所說的4位元組值。傳回值:成功返回0,失敗返回-1typedef
Time of Update: 2017-02-27
一、核心如何?訊號的捕捉如果訊號的處理動作是使用者自訂函數,在訊號遞達時就調用這個函數,這稱為捕捉訊號。由於訊號處理函數的代碼是在使用者空間的,處理過程比較複雜,舉例如下:1. 使用者程式註冊了SIGQUIT訊號的處理函數sighandler。2. 當前正在執行main函數,這時發生中斷或異常切換到核心態。3. 在中斷處理完畢後要返回使用者態的main函數之前檢查到有訊號SIGQUIT遞達。4.
Time of Update: 2017-02-27
一、訊號在核心中的表示實際執行訊號的處理動作稱為訊號遞達(Delivery),訊號從產生到遞達之間的狀態,稱為訊號未決(Pending)。進程可以選擇阻塞(Block)某個訊號。被阻塞的訊號產生時將保持在未決狀態,直到進程解除對此訊號的阻塞,才執行遞達的動作。注意,阻塞和忽略是不同的,只要訊號被阻塞就不會遞達,而忽略是在遞達之後可選的一種處理動作。訊號在核心中的表示可以看作是這樣的:每個訊號都有兩個標誌位分別表示阻塞和未決,還有一個函數指標表示處理動作。訊號產生時,核心在進程式控制制塊中設定該訊
Time of Update: 2017-02-27
一、為了理解訊號,先從我們最熟悉的情境說起:1. 使用者輸入命令,在Shell下啟動一個前台進程。2. 使用者按下Ctrl-C,這個鍵盤輸入產生一個硬體中斷。3. 如果CPU當前正在執行這個進程的代碼,則該進程的使用者空間代碼暫停執行,CPU從使用者態切換到核心態處理硬體中斷。4. 終端驅動程式將Ctrl-C解釋成一個SIGINT訊號,記在該進程的PCB中(也可以說發送了一個SIGINT訊號給該進程)。5. 當某個時刻要從核心返回到該進程的使用者空間代碼繼續執行之前,首先處理PCB中記錄的訊號,
Time of Update: 2017-02-27
一、終端的概念在UNIX系統中,使用者通過終端登入系統後得到一個Shell進程,這個終端成為Shell進程的控制終端(Controlling
Time of Update: 2017-02-27
一、殭屍進程當子進程退出的時候,核心會向父進程發送SIGCHLD訊號,子進程的退出是個非同步事件(子進程可以在父進程啟動並執行任何時刻終止)子進程退出時,核心將子進程置為殭屍狀態,這個進程稱為殭屍進程,它只保留最小的一些核心資料結構,以便父進程查詢子進程的退出狀態。父進程查詢子進程的退出狀態可以用wait/waitpid函數。二、如何避免殭屍進程當一個子進程結束運行時,它與其父進程之間的關聯還會保持到父進程也正常地結束運行或者父進程調用了wait/waitpid才告終止。進程表中代表子進程的資料
Time of Update: 2017-02-27
一、exec替換進程映象在進程的建立上Unix採用了一個獨特的方法,它將進程建立與載入一個新進程映象分離。這樣的好處是有更多的餘地對兩種操作進行管理。當我們建立了一個進程之後,通常將子進程替換成新的進程映象,這可以用exec系列的函數來進行。當然,exec系列的函數也可以將當前進程替換掉。二、exec關聯函數組包含標頭檔<unistd.h>功能用exec函數可以把當前進程替換為一個新進程。exec名下是由多個關聯函數組成的一個完整系列,標頭檔<unistd.h>原型int
Time of Update: 2017-02-27
fork的作用是根據一個現有的進程複製出一個新進程,原來的進程稱為父進程(Parent Process),新進程稱為子進程(Child
Time of Update: 2017-02-27
一、什麼是進程從使用者的角度來看進程是程式的一次執行過程。從作業系統的核心來看,進程是作業系統分配的記憶體、CPU時間片等資源的基本單位。進程是資源分派的最小單位。每一個進程都有自己獨立的地址空間與執行狀態。像UNIX這樣的多任務作業系統能夠讓許多程式同時運行,每一個運行著的程式就構成了一個進程。二、進程資料結構進程的靜態描述:由三部分組成:PCB、有關程式段和該程式段對其進行操作的資料結構集。進程式控制制塊:用於描述進程情況及控制進程運行所需的全部資訊。程式碼片段:是進程中能被進程發送器在CP
Time of Update: 2017-02-27
一、fcntl函數功能:操縱檔案描述符,改變已開啟的檔案的屬性int fcntl(int fd, int cmd, ... /* arg */ );cmd的取值可以如下:複製檔案描述符F_DUPFD (long)設定/擷取檔案描述符標誌F_GETFD (void)F_SETFD (long)設定/擷取檔案狀態標誌F_GETFL (void)F_SETFL
Time of Update: 2017-02-27
一、讀取檔案中繼資料int stat(const char *path, struct stat *buf);int fstat(int fd, struct stat *buf);int lstat(const char *path, struct stat *buf);stat() stats the file pointed to by path and fills in buf.lstat() is identical to stat(), except
Time of Update: 2017-02-27
一、目錄的訪問功能說明:開啟一個目錄原型:DIR* opendir(char *pathname);傳回值:開啟成功,返回一個目錄指標開啟失敗,則返回NULL功能說明:訪問指定目錄中下一個串連的細節原型:struct dirent* readdir(DIR *dirptr);傳回值:返回一個指向dirent結構的指標,它包含指定目錄中下一個串連的細節;沒有更多串連時,返回NULL功能說明:關閉一個已經開啟的目錄原型:int closedir
Time of Update: 2017-02-27
一、read系統調用一旦有了與一個開啟檔案描述相關連的檔案描述符,只要該檔案是用O_RDONLY或O_RDWR標誌開啟的,就可以用read()系統調用從該檔案中讀取位元組函數原型:ssize_t read(int fd, void *buf, size_t count);參數:fd :想要讀的檔案的檔案描述符buf : 指向記憶體塊的指標,從檔案中讀取來的位元組放到這個記憶體塊中count :
Time of Update: 2017-02-27
一、檔案描述符對於Linux而言,所有對裝置或檔案的操作都是通過檔案描述符進行的。當開啟或者建立一個檔案的時候,核心向進程返回一個檔案描述符(非負整數)。後續對檔案的操作只需通過該檔案描述符,核心記錄有關這個開啟檔案的資訊(file結構體)。一個進程啟動時,預設開啟了3個檔案,標準輸入、標準輸出、標準錯誤,對應檔案描述符是0(STDIN_FILENO)、1(STDOUT_FILENO)、2(STDERR_FILENO),這些常量定義在unistd.h標頭檔中。fileno:將檔案指標轉換為檔案描
Time of Update: 2017-02-27
一、read/write 函數read函數從開啟的裝置或檔案中讀取資料。#include <unistd.h>ssize_t read(int fd, void *buf, size_t