进程间通信之:管道

时间:2013-09-13来源:网络

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()函数,当然这种调用不是很好的解决方法,在后面学到进程之间的同步与互斥机制之后,请读者自行修改本小节的实例程序。

1 2 3 4 5

关键词: 进程 管道 Linux 操作系统 系统调用

加入微信
获取电子行业最新资讯
搜索微信公众号:EEPW

或用微信扫描左侧二维码

相关文章

查看电脑版