• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            天下

            記錄修行的印記

            pipe、dup、dup2、wait、waitpid、fork函數(shù)說明

            pipe、dup、dup2、wait、waitpid、fork函數(shù)說明
            int pipe(int fd[2]);
            功能:創(chuàng)建一個簡單的管道,若成功則為數(shù)組fd分配兩個文件描述符,其中fd[
            0] 用于讀取管道,fd[1]用于寫入管道。
            返回:成功返回0,失敗返回
            -1

            管道是Linux 支持的最初Unix IPC形式之一,具有以下特點:
            管道是半雙工的,數(shù)據(jù)只能向一個方向流動;需要雙方通信時,需要建立起兩個管道; 只能用于父子進程或者兄弟進程之間(具有親緣關(guān)系的進程); 單獨構(gòu)成一種獨立的文件系統(tǒng):管道對于管道兩端的進程而言,就是一個文件,但它不是普通的文件,它不屬于某種文件系統(tǒng),而是自立門戶,單獨構(gòu)成一種文件系 統(tǒng),并且只存在與內(nèi)存中。 數(shù)據(jù)的讀出和寫入:一個進程向管道中寫的內(nèi)容被管道另一端的進程讀出。寫入的內(nèi)容每次都添加在管道緩沖區(qū)的末尾,并且每次都是從緩沖區(qū)的頭部讀出數(shù)據(jù)。

            但值得我們注意的是:管道它有自身的特點。
             (
            1)管道通信是單向的,并且遵守先進先出的原則,即先寫入的數(shù)據(jù)先讀出。
             (
            2)管道是一個無結(jié)構(gòu),無固定大小的字節(jié)流。
             (
            3)兩個返回的文件描述符以一種特殊的方式連接起來.寫到fd[1]的數(shù)據(jù)都可以從fd[0]中讀回來.

            向管道中寫入數(shù)據(jù)時,linux將不保證寫入的原子性,管道緩沖區(qū)一有空閑區(qū)域,寫進程就會試圖向管道寫入數(shù)據(jù)。如果讀進程不讀走管道緩沖區(qū)中的數(shù)據(jù),那么寫操作將一直阻塞。


            int dup(int fd) 
            復(fù)制一個存在的文件描述符,返回當前可用的最小文件描述符。。。比如當前文件描述符已經(jīng)到了100,使用 dup(
            100) ,將返回 101 ,101這個文件描述符擁有100的所有東西,復(fù)制了嘛。。。

            int dup2(int fd, int fd2)
            是可以指定一個文件描述符(fd2)來使用,如果fd2已經(jīng)打開,則會先將其關(guān)閉,如果 fd
            ==fd2 ,直接返回 fd2 且不關(guān)閉。
            實際上 fcntl 也能完成這2個函數(shù)的功能,只是對于 dup2 來說,fcntl 是調(diào)用2個函數(shù),而 dup2 是一個原子操作。


            dup函數(shù)的作用:復(fù)制一個現(xiàn)有的句柄,產(chǎn)生一個與“源句柄特性”完全一樣的新句柄(也即生成一個新的句柄號,并關(guān)聯(lián)到同一個設(shè)備)

            dup2函數(shù)的作用:復(fù)制一個現(xiàn)有的句柄到另一個句柄上,目標句柄的特性與“源句柄特性”完全一樣(也即首先關(guān)閉目標句柄,與設(shè)備斷連,接著從源句柄完全拷貝復(fù)制到目標句柄)


            wait和waitpid函數(shù)
            頭文件
            #include
            <sys/types.h>
            #include
            <sys/wait.h>
            函數(shù) pid_t wait (
            int * status);
            進程一旦調(diào)用了 wait,就 立即阻塞自己,由wait自動分析是否當前進程的某個子進程已經(jīng)退出,如果讓它找到了這樣一個已經(jīng)變成僵尸的子進程,wait 就會收集這個子進程的信息, 并把它徹底銷毀后返回;如果沒有找到這樣一個子進程,wait就會一直阻塞在這里,直到有一個出現(xiàn)為止。 
            wait(等待子進程中斷或結(jié)束)

            wait()會暫時停止目前進程的執(zhí)行,直到有信號來到或子進程結(jié)束。如果在調(diào)用wait()時子進程已經(jīng)結(jié)束,則wait()會立即返回子進程結(jié)束狀態(tài)值。子進程的結(jié)束狀態(tài)值會由參數(shù)status 返回,而子進程的進程識別碼也會一快返回。如果不在意結(jié)束狀態(tài)值,則參數(shù)status 可以設(shè)成NULL。子進程的結(jié)束狀態(tài)值請參考waitpid()。
            返回值
            如果執(zhí)行成功則返回子進程識別碼(PID),如果有錯誤發(fā)生則返回
            -1。失敗原因存于errno 中。


            waitpid(等待子進程中斷或結(jié)束)
            相關(guān)函數(shù) wait,fork
            表頭文件
            #include
            <sys/types.h>
            #include
            <sys/wait.h>
            定義函數(shù) pid_t waitpid(pid_t pid,
            int * status,int options);
            函數(shù)說明
            waitpid()會暫時停止目前進程的執(zhí)行,直到有信號來到或子進程結(jié)束。如果在調(diào)用waitpid()時子進程已經(jīng)結(jié)束,則waitpid()會立即返回子進程結(jié)束狀態(tài)值。子進程的結(jié)束狀態(tài)值會由參數(shù)status 返回,而子進程的進程識別碼也會一快返回。如果不在意結(jié)束狀態(tài)值,則參數(shù)status 可以設(shè)成NULL。

            參數(shù)pid 為欲等待的子進程識別碼,其他數(shù)值意義如下:
            pid
            <-1 等待進程組識別碼為pid 絕對值的任何子進程。
            pid
            =-1 等待任何子進程,相當于wait()。
            pid
            =0 等待進程組識別碼與目前進程相同的任何子進程。
            pid
            >0 等待任何子進程識別碼為pid 的子進程。


            目前在Linux中只支持WNOHANG和WUNTRACED兩個選項,
            WNOHANG 如果沒有任何已經(jīng)結(jié)束的子進程則馬上返回,不予以等待。
            WUNTRACED 如果子進程進入暫停執(zhí)行情況則馬上返回,但結(jié)束狀態(tài)不予以理會。

            如果我們不想使用它們,也可以把options設(shè)為0,如:
            ret
            =waitpid(-1,NULL,0);

            如果使用了WNOHANG參數(shù)調(diào)用waitpid,即使沒有子進程退出,它也會立即返回,不會像wait那樣永遠等下去。

            而WUNTRACED參數(shù),用于跟蹤調(diào)試,極少用到,就不說了。
            查看linux源代碼 unistd.h 我們會發(fā)現(xiàn),其實 wait 就是經(jīng)過包裝的 waitpid:
            static inline pid_t wait(int * wait_stat)
            {
                
            return waitpid(-1,wait_stat,0);
            }

            可以用kill函數(shù)殺死子進程
            kill(childPid,SIGKILL);


            子進程的結(jié)束狀態(tài)返回后存于status,下面有幾個宏可判別結(jié)束情況:
            WIFEXITED(status)如果子進程正常結(jié)束則為非0值。
            WEXITSTATUS(status)取得子進程exit()返回的結(jié)束代碼,一般會先用WIFEXITED 來判斷是否正常結(jié)束才能使用此宏。
            WIFSIGNALED(status)如果子進程是因為信號而結(jié)束則此宏值為真
            WTERMSIG(status) 取得子進程因信號而中止的信號代碼,一般會先用WIFSIGNALED 來判斷后才使用此宏。
            WIFSTOPPED(status) 如果子進程處于暫停執(zhí)行情況則此宏值為真。一般只有使用WUNTRACED 時才會有此情況。
            WSTOPSIG(status) 取得引發(fā)子進程暫停的信號代碼,一般會先用WIFSTOPPED 來判斷后才使用此宏。

            if (WIFEXITED(status)) 
            {
                printf(
            "exited, status=%d/n", WEXITSTATUS(status));

            else if (WIFSIGNALED(status)) {
                printf(
            "killed by signal %d/n", WTERMSIG(status));

            else if (WIFSTOPPED(status)) {
                printf(
            "stopped by signal %d/n", WSTOPSIG(status));

            else if (WIFCONTINUED(status)) {
                printf(
            "continued/n");
            }

            返回值
            如果執(zhí)行成功則返回子進程識別碼(PID),如果有錯誤發(fā)生則返回
            -1。失敗原因存于errno 中。


            fork函數(shù)
            Create a 
            new process

            程序段里用了fork();之后程序出了分岔,派生出了兩個進程。具體哪個先運行就看該操作的系統(tǒng)的調(diào)度算法了。
            函數(shù)返回2次.
            返回值得在子進程中pid的值為0,通過getpid可以獲取子進程的進程id;

            返回值:
            A value of zero to the child process; and the process ID of the child process to the parent process. 
            Both processes 
            continue to execute from the fork() function. If an error occurs, fork() returns -1 to the parent and sets errno.

            #include 
            <sys/types.h>
            #include 
            <process.h>
            int main() 
            {
                pid_t pid; 

                puts(
            "<1>");
                pid
            =fork(); 
                
            if (pid < 0) {
                    printf(
            "error in fork! \r\n"); 
                }
                
            else if (pid == 0) {
                    printf(
            "i am the child process, my process id is %d \r\n",getpid()); 
                }
                
            else {
                    printf(
            "i am the parent process, my process id is %d \r\n",getpid()); 
                }

                puts(
            "<2>");
                
            return 0;
            }

            posted on 2012-08-09 14:36 天下 閱讀(2393) 評論(0)  編輯 收藏 引用 所屬分類: Linux編程

            <2011年11月>
            303112345
            6789101112
            13141516171819
            20212223242526
            27282930123
            45678910

            導(dǎo)航

            統(tǒng)計

            常用鏈接

            留言簿(4)

            隨筆分類(378)

            隨筆檔案(329)

            鏈接

            最新隨筆

            搜索

            最新評論

            久久人爽人人爽人人片AV | 99久久国产宗和精品1上映 | 日韩电影久久久被窝网| 色99久久久久高潮综合影院| 久久久久综合网久久| 久久九九免费高清视频| 中文字幕无码精品亚洲资源网久久| 国内精品久久久久伊人av| 久久天天躁狠狠躁夜夜2020老熟妇 | 午夜久久久久久禁播电影| 国产真实乱对白精彩久久| 久久综合噜噜激激的五月天| 91久久精品视频| 99re这里只有精品热久久| 久久无码高潮喷水| 国产呻吟久久久久久久92| 精品久久久久久无码中文字幕一区 | 97久久国产亚洲精品超碰热 | 亚洲人成网站999久久久综合| 97精品伊人久久久大香线蕉| 午夜精品久久久久9999高清| 久久最近最新中文字幕大全| 一本色道久久综合亚洲精品| 国产精品久久久久久久人人看| 久久青青国产| 狠狠色综合久久久久尤物| 97久久精品无码一区二区| 久久99精品久久只有精品| 精品无码久久久久国产| 久久夜色精品国产欧美乱| 伊人久久综合精品无码AV专区| 久久亚洲AV成人无码软件| 综合久久久久久中文字幕亚洲国产国产综合一区首 | 久久天天躁狠狠躁夜夜躁2014| 免费观看成人久久网免费观看| 99久久这里只有精品| 亚洲综合婷婷久久| 美女久久久久久| 一本久久知道综合久久| 久久这里只有精品18| 国内精品伊人久久久久|