OS X下UNIX環境高級編程(第三版)學習日誌-第一章ChapterI,程序和進程

  1. 程序和進程函數

    程序是一個可執行文件,進程是程序的執行實例,unix系統中,每一個進程都有一個惟一的數字標識符,被稱爲進程ID。spa

  2. #include "apue.h"
    
    int main(void){
        printf("hello world form process ID %ld\n",(long)getpid());
        exit(0);
    }

    重點:%ld表示打印長整型線程

    getpid()函數,返回自身的進程id,返回值類型爲pid_t,若是要輸出,能夠(long)強轉成長整型,使用長整型能夠提升可移植性,推測:防止某個運行環境整型太短的狀況發生。unix

  3. 進程控制指針

    有3個用於進程控制的主要函數:fork,exec,waitpid。code

  4. #include "apue.h"
    int main(void){
        char buf[MAXLINE];
        pid_t pid;
        int status;
    
        printf("%% ");
        while(fgets(buf,MAXLINE,stdin)!=NULL){
            if(buf[strlen(buf)-1]=='\n')
                buf[strlen(buf)-1]=0;//replace the last char with null
            if((pid=fork())<0){
                err_sys("fork error");
            }else if(pid==0){   /*child*/
                execlp(buf,buf,(char *)0);
                err_ret("couldn't execute:%s",buf);
                exit(127);
            }
    
            /*parent*/
            if((pid=waitpid(pid,&status,0))<0)
                err_sys("wait pid error");
            printf("%% ");
        }
        exit(0);
    }

    該例程實現的功能是輸入一個命令並執行,命令必須是$PATH指定的目錄中存在的,且命令不接收參數。
orm

    重點:
進程

    fgets(buf,MAXLINE,stdin):從標準輸入讀入最大MAXLINE長度的內容到buf中,若是以換行符結尾,則將換行符替換爲0(null),這是由於execlp要求的參數是以null結束而不是以換行符結束的。get

    fork():建立一個新進程,新進程是調用進程的一個副本,稱爲子進程,fork對父進程返回進程id,對子進程則返回0(這段寫的太模糊了。。。),調用一次,返回兩次
原型

    註釋中寫了一個/*child*/和一個/*parent*/,推測這分別是父進程和子進程的執行內容,我的理解此時有兩個進程在工做,根據上文的寫的「返回兩次」,對子進程來講pid==0,那麼執行/*child*/標註下的代碼,對父進程來講pid==一個非負整數惟一標識,執行/*parent*/標註下的代碼,等待子進程返回的結果。

    execlp(buf,buf,(char *)0):第一個參數表示執行的文件路徑,第二個表示arg0,即第0個參數,(例子:ls -l:ls就是第0個參數,-l是第1個參數),man一下這個函數,原型中最後一個參數必須爲(char *)類型的空指針,這個我也不知道爲啥,百度百科的解釋是:「若是用常數0來表示一個空指針,則必須將它強制轉換爲一個字符指針,不然將它解釋爲整形參數,若是一個整形數的長度與char * 的長度不一樣,那麼exec函數的實際參數就將出錯。」,也沒說爲啥出錯。。。

    更重要的一點,若是函數調用成功,進程本身的執行代碼就會變成加載程序的代碼,execlp()後邊的代碼也就不會執行了。書裏的解釋是:用新的程序文件替換了子進程原先執行的程序文件。

    pid_t waitpid(pid_t pid, int *stat_loc, int options);返回子進程結束狀態值。 子進程的結束狀態值會由參數 status 返回,而子進程的進程識別碼也會一塊兒返回。若是不在乎結束狀態值,則參數 status 能夠設成 NULL。參數 pid 爲欲等待的子進程識別碼。

    在本例中,第二個參數爲null,options爲0,在子進程pid結束以前什麼都不作。

    5.    線程和線程ID

    一般,一個進程只有一個控制線程(thread)——某一時刻執行的一組機器指令。

    一個進程內全部線程共享同一地址空間、文件描述符、棧以及與進程相關的屬性。由於他們能訪問同一存儲區,因此各線程在訪問共享數據時須要採起同步措施以免不一致性。

一點新的知識:返回值的接收者是進程,在unix中,產生(spawn)一個進程意味着1.建立一個pid,2.執行一個可執行文件,若是沒有後者,那麼只是一個空進程(其實不曉得理解的對不對)。

歡迎看到本文的朋友們與小弟交流,或者指正文中的錯誤,共同進步。

相關文章
相關標籤/搜索