亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? 14.htm

?? UNIX環境下C編程的詳細詳細介紹
?? HTM
?? 第 1 頁 / 共 5 頁
字號:
<html>

<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<meta name="GENERATOR" content="Microsoft FrontPage 3.0">
<title>C:\WINDOWS\Desktop\UnixProg\7.htm</title>
</head>

<body>
<font SIZE="2">

<h1 align="center">第十四章; 進程間通信 </h1>

<p>14.1 介紹 </p>

<p>在第八章中,我們說明了進程控制原語并且觀察了如何調用多個進程。但是這些進 
</p>

<p>程之間交換信息的唯一方法是經由fork或exec傳送打開文件,或通過文件系統。現 
</p>

<p>在,我們說明進程之間相互通信的其它技術-IPC(interprocess 
communication) </p>

<p>。 </p>

<p>Unix IPC已經是而且繼續是各種進程通信方式的統稱,其中極少能在所有Unix的實 
</p>

<p>現中進行移植。圖14.1摘要列出了不同實現所支持的不同形式的IPC。 
</p>

<p>圖14.1 UNIX IPC 摘要 </p>

<p>正如上圖所示,不管哪一種Unix實現,我們都可依靠的唯一一種IPC是半雙工的管 
</p>

<p>道(pipes)。圖中前7種IPC通常限于同一臺主機的各個進程間的IPC。最后二種; 
</p>

<p>套接口和流,是支持不同主機上各個進程間IPC。(關于網絡IPC的詳細情況,請參 
</p>

<p>見Stevens[1990]。)雖然中間三種形式的IPC(消息隊列、信號量以及共享存儲器 
</p>

<p>)在圖中說明為只受到系統V的支持,但是在大多數制造商所支持的,從貝克萊Un 
</p>

<p>ix導出的Unix系統中(例如,SunOS以及Ultrix),已經添加了這三種形式的IPC。 
</p>

<p>幾個Posix小組正在對IPC進行工作,但是最后結果還不很清楚,在1994年 
</p>

<p>甚至 </p>

<p>更遲一點與IPC有關的Posix可能還不會制定出來。 </p>

<p>我們已將與IPC有關的討論分成兩章。在本章中,我們討論經典的IPC;管道、FIF 
</p>

<p>O、消息隊列、信號量以及共享存儲器。在下一章中,我們將觀察SVR4和4.3+BSD共 
</p>

<p>同支持的IPC的某些高級特征,包括;流管道和命名的流管道,以及用這些更高級 
</p>

<p>形式IPC,我們可以做的一些事情。 </p>

<p>14.2 管道 </p>

<p>管道是Unix IPC的最老形式,并且所有Unix系統都提供此種通信機制,管道有兩種 
</p>

<p>限制; </p>

<p>1. 它們是半雙工的。數據只在一個方向流動。 </p>

<p>2. 
它們只能在具有公共祖先的進程之間使用。通常,一個管道由一個進程創建, 
</p>

<p>然后該進程調用fork,此后父、子進程之間就可應用該管道。 </p>

<p>我們將會看到流管道(15.2節)沒有第一種限制,FIFO(14.5節)和命名流管道( 
</p>

<p>15.5節)則沒有第二種限制。盡管有這兩種限制,半雙工管道仍是最常用的IPC形 
</p>

<p>式。 </p>

<p>管道是由調用pipe函數而創建的。 </p>

<p>#include &lt;unistd.h&gt; </p>

<p>int pipe(int filedes[2]) ; </p>

<p>返回:若成功為0,出錯為-1 </p>

<p>經由參數filedes返回兩個文件描述符;filedes[0]是為讀而打開,filedes[1]是 
</p>

<p>為寫而打開的。filedes[1]的輸出是filedes[0]的輸入。 </p>

<p>有兩種方法來描畫一個管道,如圖14.2中所示。左半圖顯示了管道的兩端在一個進 
</p>

<p>甚至 </p>

<p>更遲一點與IPC有關的Posix可能還不會制定出來。 </p>

<p>我們已將與IPC有關的討論分成兩章。在本章中,我們討論經典的IPC;管道、FIF 
</p>

<p>O、消息隊列、信號量以及共享存儲器。在下一章中,我們將觀察SVR4和4.3+BSD共 
</p>

<p>同支持的IPC的某些高級特征,包括;流管道和命名的流管道,以及用這些更高級 
</p>

<p>形式IPC,我們可以做的一些事情。 </p>

<p>14.2 管道 </p>

<p>管道是Unix IPC的最老形式,并且所有Unix系統都提供此種通信機制,管道有兩種 
</p>

<p>限制; </p>

<p>1. 它們是半雙工的。數據只在一個方向流動。 </p>

<p>2. 
它們只能在具有公共祖先的進程之間使用。通常,一個管道由一個進程創建, 
</p>

<p>然后該進程調用fork,此后父、子進程之間就可應用該管道。 </p>

<p>我們將會看到流管道(15.2節)沒有第一種限制,FIFO(14.5節)和命名流管道( 
</p>

<p>15.5節)則沒有第二種限制。盡管有這兩種限制,半雙工管道仍是最常用的IPC形 
</p>

<p>式。 </p>

<p>管道是由調用pipe函數而創建的。 </p>

<p>#include &lt;unistd.h&gt; </p>

<p>int pipe(int filedes[2]) ; </p>

<p>返回:若成功為0,出錯為-1 </p>

<p>經由參數filedes返回兩個文件描述符;filedes[0]是為讀而打開,filedes[1]是 
</p>

<p>為寫而打開的。filedes[1]的輸出是filedes[0]的輸入。 </p>

<p>有兩種方法來描畫一個管道,如圖14.2中所示。左半圖顯示了管道的兩端在一個進 
</p>

<p>圖14.4 從父進程到子進程的管道 </p>

<p>對于從子進程到父進程的管道,父進程關閉 fd[1],子進程關閉fd[0]。 
</p>

<p>當管道的一端被關閉后,下列規定起作用; </p>

<p>1. 當讀一個寫端已被關閉的管道時,在所有數據都被讀取后,read返回0,以指示 
</p>

<p>達到了文件結束處。(從技術方面考慮,在管道的寫端還有進程時,就不會產生文 
</p>

<p>件的結束。可以復制一個管道的描述符,使得有多個進程具有寫打開文件描述符。 
</p>

<p>但是,通常一個管道只有一個讀進程,一個寫進程。在下一節介紹FIFO時,我們會 
</p>

<p>看到對于一個單一的FIFO常常有多個寫進程)。 </p>

<p>2. 如果寫一個讀端已被關閉的管道,則產生信號SIGPIPE。如果忽略該信號或者捕 
</p>

<p>捉該信號并從其處理程序返回,則Write出錯返回,errno設置為EPIPE。 
</p>

<p>在寫管道時,常數PIPE_BUF規定了核中管道緩存器的大小。如果對管道進行write 
</p>

<p>調用,而且要求寫的字節數小于等于PIPE_BUF,則此操作不會與其它進程對同一管 
</p>

<p>道(或FIFO)的write操作穿插進行。但是,若有多個進程同時寫一個管道(或FI 
</p>

<p>FO),而且某個或某些進程要求寫的字節數超過PIPE_BUF字節數,則數據可能會與 
</p>

<p>其它寫操作的數據相穿插。 </p>

<p>實例 </p>

<p>程序14.1中創建了一個從父進程到子進程的管道,并且父進程經由該管道向子 
</p>

<p>進程傳送數據。 </p>

<p>#include &quot;ourhdr.h&quot; </p>

<p>int </p>

<p>main(void) </p>

<p>{ </p>

<p>int n, fd[2]; </p>

<p>pid_t pid; </p>

<p>char line[MAXLINE]; </p>

<p>if (pipe(fd) &lt; 0) </p>

<p>err_sys(&quot;pipe error&quot;); </p>

<p>if ( (pid = fork()) &lt; 0) </p>

<p>err_sys(&quot;fork error&quot;); </p>

<p>else if (pid &gt; 0) { /* parent */ </p>

<p>close(fd[0]); </p>

<p>write(fd[1], &quot;hello world\n&quot;, 12); </p>

<p>} else { /* child */ </p>

<p>close(fd[1]); </p>

<p>n = read(fd[0], line, MAXLINE); </p>

<p>write(STDOUT_FILENO, line, n); </p>

<p>} </p>

<p>exit(0); </p>

<p>} </p>

<p>程序14.1 經由管道父進程向子進程傳送數據 </p>

<p>在上面的例子中,我們直接對管道描述符調用read和write。更為有益的是將管道 
</p>

<p>描述符復制為標準輸入和標準輸出。在此之后通常子進程調用exec,執行另一道程 
</p>

<p>序,開從標準輸入(已創建的管道)或將數據寫至其標準輸出(管道)。 
</p>

<p>實例 </p>

<p>讓我們編寫一道程序,其功能是每次一頁顯示已產生的輸出。已經有很多Unix公用 
</p>

<p>程序具有分頁功能,因此我們無需再構造一個新的分頁程序,而是調用用戶最喜愛 
</p>

<p>的分頁程序。為了避免先將所有數據寫到一個臨時文件中,然后再調用系統中有關 
</p>

<p>程序顯示該文件,我們希望將輸出通過管道直接送到分頁程序。為此,先創建一個 
</p>

<p>管道,一個子進程,使子進程的標準輸入成為管道的讀端,然后exec用戶喜愛的分 
</p>

<p>頁程序。程序14.2顯示了如何實現這些操作。(本例要求在命令行中有一個參 
</p>

<p>數說明要顯示的文件的名稱。通常,這種類型的程序要求在終端上顯示的數據已經 
</p>

<p>在存儲器中。) </p>

<p>#include &lt;sys/wait.h&gt; </p>

<p>#include &quot;ourhdr.h&quot; </p>

<p>#define DEF_PAGER &quot;/usr/bin/more&quot; /* default pager program */ </p>

<p>int </p>

<p>main(int argc, char *argv[]) </p>

<p>{ </p>

<p>int n, fd[2]; </p>

<p>pid_t pid; </p>

<p>char line[MAXLINE], *pager, *argv0; </p>

<p>FILE *fp; </p>

<p>if (argc != 2) </p>

<p>err_quit(&quot;usage: a.out &lt;pathname&gt;&quot;); </p>

<p>if ( (fp = fopen(argv[1], &quot;r&quot;)) == NULL) </p>

<p>err_sys(&quot;can't open %s&quot;, argv[1]); </p>

<p>if (pipe(fd) &lt; 0) </p>

<p>err_sys(&quot;pipe error&quot;); </p>

<p>if ( (pid = fork()) &lt; 0) </p>

<p>err_sys(&quot;fork error&quot;); </p>

<p>else if (pid &gt; 0) { </p>

<p>/* parent */ </p>

<p>close(fd[0]); /* close read end */ </p>

<p>/* parent copies argv[1] to pipe */ </p>

<p>while (fgets(line, MAXLINE, fp) != NULL) { </p>

<p>n = strlen(line); </p>

<p>if (write(fd[1], line, n) != n) </p>

<p>err_sys(&quot;write error to pipe&quot;); </p>

<p>} </p>

<p>if (ferror(fp)) </p>

<p>err_sys(&quot;fgets error&quot;); </p>

<p>close(fd[1]); /* close write end of pipe for reader */ </p>

<p>if (waitpid(pid, NULL, 0) &lt; 0) </p>

<p>err_sys(&quot;waitpid error&quot;); </p>

<p>exit(0); </p>

<p>} else { </p>

<p>/* child */ </p>

<p>close(fd[1]); /* close write end */ </p>

<p>if (fd[0] != STDIN_FILENO) { </p>

<p>if (dup2(fd[0], STDIN_FILENO) != STDIN_FILENO) </p>

<p>err_sys(&quot;dup2 error to stdin&quot;); </p>

<p>close(fd[0]); /* don't need this after dup2 */ </p>

<p>} </p>

<p>/* get arguments for execl() */ </p>

<p>if ( (pager = getenv(&quot;PAGER&quot;)) == NULL) </p>

<p>pager = DEF_PAGER; </p>

<p>if ( (argv0 = strrchr(pager, '/')) != NULL) </p>

<p>argv0++; /* step past rightmost slash */ </p>

<p>else </p>

<p>argv0 = pager; /* no slash in pager */ </p>

<p>if (execl(pager, argv0, (char *) 0) &lt; 0) </p>

<p>err_sys(&quot;execl error for %s&quot;, pager); </p>

<p>} </p>

<p>} </p>

<p>程序14.2 將文件復制到分頁程序 </p>

<p>在調用fork之前先創建一個pipe。fork之后父進程關閉其讀端,子進程關閉其寫端 
</p>

<p>。子進程然后調用dup2,使其標準輸入成為管道的讀端。當執行分頁程序時,其標 
</p>

<p>準輸入將是管道的讀端。 </p>

<p>當我們將一個描述符復制到另一個時(在子進程中,fd[0]復制到標準輸入),應 
</p>

<p>當注意該描述符的值并不已經是所希望的值。如果該描述符已經具有所希望的值, 
</p>

<p>并且我們先調用dup2,然后close則將關閉在此進程中只有該單個描述符所代表的 
</p>

<p>打開文件。(請回憶3.12節中所述,當dup2中的兩個參數值相等時的操作。)在本 
</p>

<p>程序中,如果shell沒有打開標準輸入,那么程序開始處的fopen應已使用描述符0 
</p>

<p>,也就是最小末使用的描述符,所以fd[0]決不會等于標準輸入。盡管如此,只要 
</p>

<p>先調用dup2,然后close以復制一個描述符到另一個,作為一種保護性的編程措施 
</p>

<p>,我們總是先將兩個描述符進行比較。 </p>

<p>請注意,我們是如何使用環境變量PAGER而獲得用戶分頁程序名稱的。如果這種操 
</p>

<p>作沒有成功,則使用系統默認值。這是環境變量的常見用法。 </p>

<p>實例 </p>

<p>請回憶8.8節中的五個函數TELL_WAIT、TELL_PARENT、TELL_CHILD、WAIT_PARENT以 </p>

<p>及WAIT_CHILD。在程序10.17中,我們提供了一個使用信號的實現。程序14.3則是 
</p>

<p>一個使用管道的實現。 </p>

<p>如圖14.5所示,我們在fork之前創建了兩個管道。 </p>

<p>圖14.5 用兩個管道實現父-子進程的同步 </p>

<p>父進程在調用TELL_CHILD時經由上一個管道寫一個字符&quot;P&quot;,子進程在調用TELL_P 
</p>

<p>ARENT時,經由下一個管道寫一個字符&quot;C&quot;。相應的WAIT_XXX函數調用read讀一個字 
</p>

<p>符,沒有讀到字符時阻塞(睡眠等待)。 </p>

<p>請注意,每一個管道都有一個額外的讀取進程,這沒有關系。也就是說除了子進程 
</p>

<p>從pfd1[0]讀取,父進程也有上一個管道的讀端。因為父進程并沒有執行對該管道 

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
日韩福利电影在线观看| 亚洲欧洲在线观看av| 一本色道**综合亚洲精品蜜桃冫| 国内精品国产成人| 精品一区二区三区视频在线观看| 日韩福利电影在线观看| 美女任你摸久久| 美女任你摸久久| 国产综合色精品一区二区三区| 国产在线精品一区在线观看麻豆| 美国三级日本三级久久99| 奇米888四色在线精品| 久色婷婷小香蕉久久| 国产成人在线视频免费播放| 99久久久久久| 欧美日韩在线免费视频| 7777精品伊人久久久大香线蕉的| 日韩无一区二区| 久久久久久久久久久99999| 亚洲国产成人一区二区三区| 日韩理论电影院| 香港成人在线视频| 国产在线播放一区三区四| 成人免费高清在线| 欧美性大战xxxxx久久久| 日韩免费福利电影在线观看| 国产亚洲综合在线| 亚洲精品国产视频| 久88久久88久久久| 色诱亚洲精品久久久久久| 欧美久久久一区| 久久美女高清视频| 亚洲精品视频在线| 精品影院一区二区久久久| 成人动漫在线一区| 制服丝袜日韩国产| 亚洲色图欧美激情| 久久国产生活片100| 色综合久久久久综合| 日韩欧美中文一区| 亚洲欧美另类在线| 国产一区二区三区av电影| 在线观看一区不卡| 国产精品久久久久久久午夜片| 午夜视黄欧洲亚洲| jlzzjlzz国产精品久久| 欧美一区二区三区视频在线观看| 中文字幕亚洲电影| 韩国三级电影一区二区| 欧美精品vⅰdeose4hd| 国产精品国产a| 国产传媒一区在线| 日韩欧美123| 日韩精品国产欧美| 一本到高清视频免费精品| 久久久久久一二三区| 五月天一区二区| 在线亚洲欧美专区二区| 国产精品久久久久一区二区三区 | 日韩欧美一级在线播放| 亚洲综合一区二区精品导航| 国产成人精品影院| 国产欧美一区二区精品忘忧草 | 在线影院国内精品| 综合中文字幕亚洲| 不卡视频一二三四| 国产女同互慰高潮91漫画| 国产麻豆9l精品三级站| 欧美电视剧在线看免费| 日本欧美一区二区| 欧美精品一卡二卡| 青青草97国产精品免费观看无弹窗版| 欧美亚洲综合在线| 亚洲成a人片综合在线| 欧美亚洲免费在线一区| 午夜国产精品一区| 91精品麻豆日日躁夜夜躁| 日韩激情视频网站| 日韩一区二区三区视频在线| 亚洲日本在线看| 91黄色激情网站| 亚洲成人av一区二区| 91精品国产麻豆| 六月丁香婷婷色狠狠久久| 欧美一级爆毛片| 国产一区二区三区久久悠悠色av| www一区二区| 福利电影一区二区| 亚洲天堂2014| 色伊人久久综合中文字幕| 一级女性全黄久久生活片免费| 色国产综合视频| 日韩激情视频在线观看| 2020国产成人综合网| 国产精品影视天天线| 国产精品全国免费观看高清| 91精品福利在线| 日韩成人精品在线观看| 欧美成人艳星乳罩| 99久久99久久精品国产片果冻 | 欧美一区二区三区视频免费播放| 另类人妖一区二区av| 国产欧美一区二区在线| 在线免费观看日本一区| 麻豆成人综合网| 亚洲国产精品黑人久久久| 欧美性色黄大片手机版| 狠狠色丁香婷综合久久| 亚洲欧美日韩人成在线播放| 欧美精品vⅰdeose4hd| 成人一道本在线| 天天操天天色综合| 国产午夜精品美女毛片视频| 欧美综合色免费| 国产麻豆日韩欧美久久| 午夜免费久久看| 中文字幕精品三区| 欧美一区二区三区影视| 色综合天天综合在线视频| 精品在线免费观看| 亚洲一区二区三区四区五区中文| 精品99一区二区三区| 色视频成人在线观看免| 国产成人在线免费| 日韩成人精品在线观看| 一区二区三区精品在线观看| 久久久精品tv| 精品99999| 日韩欧美高清一区| 欧美视频精品在线| 一本大道久久a久久精品综合| 国产一区二区三区免费| 日韩国产精品91| 亚洲国产综合视频在线观看| 国产精品国产三级国产aⅴ入口| 欧美一区二区黄| 欧美午夜电影在线播放| 成人av第一页| 国产91精品精华液一区二区三区| 美女高潮久久久| 日本成人在线电影网| 亚洲成人一区二区| 亚洲精品免费电影| 亚洲少妇30p| 中文一区二区完整视频在线观看 | 国产精品二区一区二区aⅴ污介绍| 日韩欧美国产综合| 3d动漫精品啪啪一区二区竹菊| 91成人看片片| 色综合久久综合网| 色偷偷久久人人79超碰人人澡| 成人午夜视频在线观看| 成人综合婷婷国产精品久久免费| 国产成人在线视频免费播放| 国产suv精品一区二区883| 国产乱码精品1区2区3区| 国产精品一二三在| 成人网男人的天堂| caoporn国产一区二区| 成人av在线网站| 色综合天天综合狠狠| 在线观看日韩一区| 欧美老肥妇做.爰bbww| 91精品国产一区二区三区| 欧美一级xxx| 久久久久9999亚洲精品| 国产精品久久久久久久久久免费看 | 欧美韩国日本不卡| 136国产福利精品导航| 一区二区三区丝袜| 亚洲一区在线电影| 日韩精品欧美成人高清一区二区| 麻豆91精品91久久久的内涵| 国产毛片精品视频| 91社区在线播放| 欧美日韩国产综合一区二区| 欧美成人精品1314www| 国产精品你懂的| 亚洲一区二区视频| 激情偷乱视频一区二区三区| 成人av电影在线网| 欧美日韩的一区二区| 久久免费视频一区| 综合在线观看色| 久久国产精品一区二区| www.66久久| 日韩一区二区三区免费看 | 在线视频国内自拍亚洲视频| 日韩色视频在线观看| 国产精品免费av| 老司机午夜精品99久久| 色久综合一二码| 精品国产sm最大网站| 亚洲高清不卡在线| 国产成人精品三级| 日韩一级完整毛片| 亚洲欧美日本在线| 成人免费看片app下载| 精品剧情在线观看| 亚洲第一成人在线|