文章試讀
不拘一個遍程序系列:編程序不能一個腦袋鑽到底,有時要學會變通,即所謂的曲線救國。一、二、三、四
職場規劃:一些雜七雜八的職場感悟吧。不值錢的軟件人才 精力充沛與事業成功 讓系分來得更猛烈些吧 不值錢的系統分析師
我的詩歌:都是我的打油詩,但是很值得一讀。不要工作還衣食無憂之四難歌 香格裡拉美人圖
寶寶圖片:超可愛的小寶寶 寫博客
考試培訓:主要是關於考研、軟考和等級的相關題解。2009考研試題分析 2008年12月程序員試題分析 2009年軟考備考全攻略 2008年5月程序員試題解析
《精通Unix下C語言編程與項目實踐》之七
標准I/O重定向
作者:朱雲翔,胡平
11.2.4 連接標准I/O的管道模型
管道在shell中最常見的應用是連接不同進程的輸入輸出,比如使A進程的輸出變成B進程的輸入等。考察shell命令“cat pipe3.c | more”,進程“more”使用了進程“cat pipe3.c”的輸出。
例1. 分別重定向標准輸入、標准輸出、標准錯誤輸出到文件描述符fd1、fd2和fd3中。
答:復制文件描述符fd1到文件描述符0中即可重定向標准輸入,其它的類似,如以下語句所示:
dup2(fd1, 0); /* 復制fd1到文件描述符0中,更改標准輸入為fd1 */
dup2(fd2, 1); /* 復制fd2到文件描述符1中,更改標准輸出為fd2 */
dup2(fd3, 2); /* 復制fd3到文件描述符2中,更改標准錯誤輸出為fd3 */
當執行“dup2(fd1, 0)”後,文件描述符0就對應到了fd1所對應的文件中,而一些標准輸出函數,如printf、puts等仍然向描述符0中寫入內容,從而達到了重定向的效果。
模型
使用管道將父進程標准輸入連接到子進程標准輸入的方法如下:
(1) 創建管道,返回無名管道的兩個文件描述符fildes[0]和fildes[1]。
(2) 創建子進程,子進程中繼承無名管道文件描述符。
(3) 父進程關閉管道的輸出端,即關閉只讀文件描述符fileds[0]。
(4) 父進程將標准輸出stdout,文件描述符1)重定向為文件描述符fileds[1]。
(5) 子進程關閉管道的輸入端,即關閉只寫文件描述符fileds[1]。
(6) 子進程將標准輸入stdin,文件描述符0)重定向為文件描述符fileds[0]。
最終創建的管道流如圖11-7所示:
圖11-7 父子進程標准I/O管道父進程流向子進程)
實例
本處設計一個將父進程標准輸出流連接到子進程標准輸入流的管道,父進程向stdout輸出的“Hello!”直接轉移到子進程的stdin,由子進程“gets(buf)”語句所獲取。如代碼11-6所示:
代碼11-6 父進程的輸出連接子進程的輸入通信實例節自/code/chapter11/pipe3.c)
#include <unistd.h>
#include <stdio.h>
int main()
{
int fildes[2];
pid_t pid;
int i, j;
char buf[256];
if (pipe(fildes) < 0 || (pid = fork()) < 0) /* 創建管道和子進程 */
{
fprintf(stderr, "error!\n");
return 1;
}
if (pid == 0)
{
/* ―――――――――――――――――子進程―――――――――――――――――― */
close(fildes[1]);
dup2(fildes[0], 0); /* 重定向stdin到fildes[0]中 */
close(fildes[0]);
gets(buf); /* 讀入輸入,其實是讀取父進程輸出 */
fprintf(stderr, "child:[%s]\n", buf);
return 2;
}
/* ―――――――――――――――――父進程―――――――――――――――――― */
close(fildes[0]);
dup2(fildes[1], 1); /* 重定向stdout到fildes[1]中 */
close(fildes[1]);
puts("Hello!"); /* 輸出,同時增加子進程的輸入信息*/
return 0;
}
編譯與運行代碼11-6:
# make pipe3
cc -O -o pipe3 pipe3.c
# ./pipe3
child:[Hello!]
上例中,父進程的標准輸出已經重定向到管道中,故父進程puts未能將結果打印到屏幕上。
相關文章:
封面 前言 目錄 策劃 作者
動態庫 變長參數 文件鎖 外設 僵死進程
定時器 I/O重定向本文出自 “編程浪子朱雲翔” 博客,請務必保留此出處http://zhuyunxiang.blog.51cto.com/653596/134458