进程间通信之:管道
4.管道使用实例
在本例中,首先创建管道,之后父进程使用fork()函数创建子进程,之后通过关闭父进程的读描述符和子进程的写描述符,建立起它们之间的管道通信。
/*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));
/*创建管道*/
if(pipe(pipe_fd)0)
{
printf(pipecreateerrorn);
exit(1);
}
/*创建一子进程*/
if((pid=fork())==0)
{
/*子进程关闭写描述符,并通过使子进程暂停1s等待父进程已关闭相应的读描述符*/
close(pipe_fd[1]);
sleep(DELAY_TIME*3);
/*子进程读取管道内容*/
if((real_read=read(pipe_fd[0],buf,MAX_DATA_LEN))>0)
{
printf(%dbytesreadfromthepipeis'%s'n,real_read,buf);
}
/*关闭子进程读描述符*/
close(pipe_fd[0]);
exit(0);
}
elseif(pid>0)
{
/*父进程关闭读描述符,并通过使父进程暂停1s等待子进程已关闭相应的写描述符*/
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);
}
/*关闭父进程写描述符*/
close(pipe_fd[1]);
/*收集子进程退出信息*/
waitpid(pid,NULL,0);
exit(0);
}
}
将该程序交叉编译,下载到开发板上的运行结果如下所示:
$./pipe
Parentwrote17bytes:'PipeTestProgram'
17bytesreadfromthepipeis'PipeTestProgram'
5.管道读写注意点
n 只有在管道的读端存在时,向管道写入数据才有意义。否则,向管道写入数据的进程将收到内核传来的SIGPIPE信号(通常为Brokenpipe错误)。
n 向管道写入数据时,Linux将不保证写入的原子性,管道缓冲区一有空闲区域,写进程就会试图向管道写入数据。如果读进程不读取管道缓冲区中的数据,那么写操作将会一直阻塞。
n 父子进程在运行时,它们的先后次序并不能保证,因此,在这里为了保证父子进程已经关闭了相应的文件描述符,可在两个进程中调用sleep()函数,当然这种调用不是很好的解决方法,在后面学到进程之间的同步与互斥机制之后,请读者自行修改本小节的实例程序。
linux操作系统文章专题:linux操作系统详解(linux不再难懂)linux相关文章:linux教程
数字通信相关文章:数字通信原理
通信相关文章:通信原理
评论