進程間通信之:管道
4.管道使用實例
在本例中,首先創(chuàng)建管道,之后父進程使用fork()函數(shù)創(chuàng)建子進程,之后通過關(guān)閉父進程的讀描述符和子進程的寫描述符,建立起它們之間的管道通信。
/*pipe.c*/
#includeunistd.h>
#includesys/types.h>
#includeerrno.h>
#includestdio.h>
#includestdlib.h>
#defineMAX_DATA_LEN256
#defineDELAY_TIME1
intmain()
{
pid_tpid;
intpipe_fd[2];
charbuf[MAX_DATA_LEN];
constchardata[]=PipeTestProgram;
intreal_read,real_write;
memset((void*)buf,0,sizeof(buf));
/*創(chuàng)建管道*/
if(pipe(pipe_fd)0)
{
printf(pipecreateerrorn);
exit(1);
}
/*創(chuàng)建一子進程*/
if((pid=fork())==0)
{
/*子進程關(guān)閉寫描述符,并通過使子進程暫停1s等待父進程已關(guān)閉相應的讀描述符*/
close(pipe_fd[1]);
sleep(DELAY_TIME*3);
/*子進程讀取管道內(nèi)容*/
if((real_read=read(pipe_fd[0],buf,MAX_DATA_LEN))>0)
{
printf(%dbytesreadfromthepipeis'%s'n,real_read,buf);
}
/*關(guān)閉子進程讀描述符*/
close(pipe_fd[0]);
exit(0);
}
elseif(pid>0)
{
/*父進程關(guān)閉讀描述符,并通過使父進程暫停1s等待子進程已關(guān)閉相應的寫描述符*/
close(pipe_fd[0]);
sleep(DELAY_TIME);
if((real_write=write(pipe_fd[1],data,strlen(data)))!=-1)
{
printf(Parentwrote%dbytes:'%s'n,real_write,data);
}
/*關(guān)閉父進程寫描述符*/
close(pipe_fd[1]);
/*收集子進程退出信息*/
waitpid(pid,NULL,0);
exit(0);
}
}
將該程序交叉編譯,下載到開發(fā)板上的運行結(jié)果如下所示:
$./pipe
Parentwrote17bytes:'PipeTestProgram'
17bytesreadfromthepipeis'PipeTestProgram'
5.管道讀寫注意點
n 只有在管道的讀端存在時,向管道寫入數(shù)據(jù)才有意義。否則,向管道寫入數(shù)據(jù)的進程將收到內(nèi)核傳來的SIGPIPE信號(通常為Brokenpipe錯誤)。
n 向管道寫入數(shù)據(jù)時,Linux將不保證寫入的原子性,管道緩沖區(qū)一有空閑區(qū)域,寫進程就會試圖向管道寫入數(shù)據(jù)。如果讀進程不讀取管道緩沖區(qū)中的數(shù)據(jù),那么寫操作將會一直阻塞。
n 父子進程在運行時,它們的先后次序并不能保證,因此,在這里為了保證父子進程已經(jīng)關(guān)閉了相應的文件描述符,可在兩個進程中調(diào)用sleep()函數(shù),當然這種調(diào)用不是很好的解決方法,在后面學到進程之間的同步與互斥機制之后,請讀者自行修改本小節(jié)的實例程序。
linux操作系統(tǒng)文章專題:linux操作系統(tǒng)詳解(linux不再難懂)linux相關(guān)文章:linux教程
數(shù)字通信相關(guān)文章:數(shù)字通信原理
通信相關(guān)文章:通信原理
評論