天天看點

《UNIX環境進階程式設計》---1.UNIX基礎知識UNIX 基礎知識

UNIX 基礎知識

一、UNIX 系統

  1. UNIX核心的接口稱之為系統調用。公用函數庫建構在系統調用接口之上。應用程式既可以使用公用函數庫,也可以使用系統調用。
  2. UNIX shell 是一個特殊的應用程式,它為其他應用程式提供了一個接口。
  3. 路徑名由斜線分隔的一個或者多個檔案名組成的序列:
    • 以斜線開頭的路徑名稱為絕對路徑名
    • 以非斜線開頭的路徑名稱為相對路徑名
    檔案系統根的名字

    /

    是一個特殊的絕對路徑名。它不包含任何其他的字元。
  4. 檢視UNIX系統

    ls

    指令的

    man

    幫助手冊:

    man 1 ls

    或者

    man -s1 ls

    • 1

      表示第一部分。由于很多指令的說明文檔過于龐大,是以 UNIX将說明文檔劃分成九個部分。常用的段有:
      • 1

        : 可執行程式或者

        shell command

        的說明
      • 2

        : 系統調用的說明
      • 3

        : 庫函數的說明
      • 4

        : 特殊檔案(通常位于

        /dev/

        )的說明
      • 8

        : 系統管理者指令的說明(通常隻有

        root

        可用)
    • ls

      表示

      shell command

      ,即待查找的目标

ls的簡要實作

#include "apue.h"
#include <dirent.h>
int main(int argc, char *argv[])
{
    DIR *dp;
    struct dirent *dirp;
    if (argc != )          //argument 
        err_quit("usage:ls directory_name");
    if ((dp = opendir(argv[])) == NULL)    //if file not exit
        err_sys("can't open %s",argv[]);
    while((dirp = readdir(dp)) != NULL)
        printf("%s\n",dirp->d_name);
    closedir(dp);
    exit();
}
           

用法:編譯後可執行檔案myls‘./myls /dev’必須加檔案名

标準輸出

例如:ls >file.list,即将ls顯示的内容标準輸出到檔案file.list上。

同理我們編寫的程式 : ./myls /dev > file.list

不帶緩沖的I/O

mycopy.c

/*
    std output from std input
*/
#include "apue.h"
#define BUFFSIZE 4096
int main(void)
{
    int n;
    char buf[BUFFSIZE];
    while((n = read(STDIN_FILENO,buf,BUFFSIZE)) > )
        if (write(STDOUT_FILENO,buf,n) != n)
            err_sys("write error");
    if(n < )
        err_sys("read error");
    exit();
}
           

用法:編譯後mycopy ,運作./mycopy >data

則表示從終端接收輸入,存進data檔案中,打開data即是我們從終端出入的内容。ctrl +D,終止輸入。

若要将一個檔案的内容複制到另一檔案,則可使用

./mycopy <data> data1

//将data的内容複制到data1中

标準I/O

/*
    std output from std input
*/
#include "apue.h"
int main(void)
{
    int c;

    /*while input enter key,the function read() begin read data(include "\n")*/
    while((c = getc(stdin)) != EOF)  //一次擷取一個元素
        if (putc(c,stdout) == EOF)
            err_sys("output error");
    if (ferror(stdin))
        err_sys("input error");

    exit();
}
           
  1. 每個程序都有一個工作目錄,有時稱他為目前工作目錄。所有的相對路徑名都是從工作目錄開始解釋。
    可以用

    chdir

    函數更改其工作目錄
  2. 登入時,

    shell

    的工作目錄設定為起始目錄
  3. UNIX系統中,每個程序都有一個唯一的數字标志符,稱為程序ID(一個非負整數)。
  4. 通常一個程序隻有一個線程。但是你也可以建立多個線程。
    • 一個程序内的所有線程共享同一個位址空間、檔案描述符、棧、程序相關屬性
    • 多線程的程式需要在各線程通路共享資料時采取措施來避免不一緻性
    • 線程也用ID辨別,但是線程ID隻有在它所屬的程序内有意義
  5. 使用者群組:
    • 使用者ID:辨別各個不同的使用者;使用者ID為0的使用者為根使用者,其登入名為

      root

      ,它具有超級使用者權限。
    • 組ID:使用者所屬的組的辨別。
    • 附屬組ID: 一個使用者可以屬于多個組,這些組就是附屬組。由附屬組的ID來辨別。

二、錯誤處理

  1. 當 UNIX 系統函數出錯時,通常會傳回一個負值,同時整型變量

    errno

    通常被設定為具有特定資訊的值。
    • 檔案

      <errno.h>

      定義了

      errno

      以及賦予它的各種常量,這些常量以

      E

      字元開頭
    • 在多線程環境中,每個線程都有屬于自己的局部

      errno

      ,以避免一個線程幹擾另一個線程。
    對于

    errno

    的使用要注意兩條規則:
    • 如果沒有出錯,則

      errno

      的值不會被清除.是以隻有在函數的傳回值指明出錯了時,檢查

      errno

      才有意義
    • 任何函數都不會将

      errno

      的值清零,且在

      <errno.h>

      中定義的所有常量都不為0
  2. strerror/perror

    函數:用于處理錯誤資訊
    #include<string.h>
    
    char *strerror(int errnum);
    
    #include<stdio.h>
    
    void perror(const char*msg);
               
    • strerror: 将

      errnum

      (通常就是

      errno

      值)映射為一個出錯消息字元串,并且傳回此字元串的指針
      • 輸入: 一個整數(通常是

        errno

        的值)
      • 輸出: 出錯消息字元串的指針(不需要使用者手動配置設定出錯消息字元串的記憶體)
    • perror: 基于

      errno

      的目前值,在标準錯誤上産生一條出錯消息,然後傳回。這條出錯消息首先是

      msg

      指向的字元串,後面是冒号,後面是一個空格,後面是對應于

      errno

      值的出錯消息,最後是一個換行符。
      • 輸入:附加的出錯消息
      • 輸出:無輸出。但是向标準錯誤上輸出一條出錯消息,這條出錯消息如上所述。
    《UNIX環境進階程式設計》---1.UNIX基礎知識UNIX 基礎知識
  3. 出錯恢複:可以将

    <errno.h>

    中定義的錯誤分成兩類:
    • 緻命性錯誤:此類錯誤無法恢複。最多隻能在螢幕上列印一條出錯消息或者将出錯消息寫入日志,然後退出。
    • 非緻命性錯誤:此類錯誤可以妥善處理。大多數非緻命性錯誤時暫時的(比如資源短缺)
    與資源相關的非緻命性錯誤包括:

    EAGAIN、ENFILE、ENOBUFS、ENOLCK、ENOSPC、EWOULDBLOCK

    .其典型的處理方法是:延遲一段時間,然後重試。
    • 有時候

      ENOMEM

      也是非緻命性出錯
    • EBUSY

      指明 共享資源正在使用是,也可視為非緻命性出錯處理
    • EINTR

      中斷一個慢速系統調用時,可以視為非緻命性出錯處理

三、時間

  1. UNIX 系統使用兩種時間:
    • 月曆時間:自 UTC 1970年1月1日 00:00:00 以來經曆過的秒數累計值。用

      time_t

      資料類型來儲存這種時間值。
    • 程序時間:也稱作CPU時間,用于度量程序使用的CPU資源。程序時間以時間滴答來計算,用

      clock_t

      資料類型儲存這種時間值。
  2. 當度量一個程序的執行時間時,UNIX系統為一個程序維護了3個程序時間值:
    • 時鐘時間: 又稱作牆上時鐘時間,是程序運作的時間總量,其值與系統中同時運作的程序數有關
    • 使用者CPU時間:執行使用者指令所用的時間量
    • 系統CPU時間:該程序執行核心程式所經曆的時間。如程序執行一個

      read

      系統調用,則核心執行該系統調用的時間計入系統 CPU 時間
    使用者CPU時間和系統CPU時間之和稱作 CPU 時間
  3. 運作

    shell

    指令

    time

    可以擷取程序的時鐘時間、使用者時間和系統時間。

    time

    的參數請參考

    man

    手冊
    《UNIX環境進階程式設計》---1.UNIX基礎知識UNIX 基礎知識