两个进程利用管道进行通信,一个读一个写。
一个管道对应着两个文件描述符,这时候需要注意读端及写端文件描述符的关闭情况。
1.关于写端文件描述符的关闭
1.1 关闭写端,那么读端会read出0个字节,如果是用select或者poll会检测出一个可读的条件,并可以读到0个字节。
1.2 如果写端没有关闭,且读端没有数据可读时,read调用会阻塞。
故要注意写端进程写完数据后要记得关闭写端的文件描述符,否则读端读完后将阻塞下去!
2.读端文件描述符的关闭
如果读端文件描述符已经关闭,并在写端继续调用write向该管道写数据。则
写进程会收到SIGPIPE信号,默认情况下写进程会被终止。
若捕获、阻止、忽略了SIGPIPE信号,则 write系统调用会返回-1,errno被设置为EPIPE错误
当然写进程监测到该情况以后意味着管道的读端已经关闭了,就不要再写了,呵呵!
一个示例程序
#include
#include
#include
#include
#include
#include
int main()
{
int data_processed;
int file_pipes[2];
const char some_data[]={"123"};
char buffer[BUFSIZ+1];
pid_t fork_result;
memset(buffer,0,sizeof(buffer));
if(pipe(file_pipes)==0)
{
fork_result = fork();
if(-1 == fork_result)
{
printf("error while fork ");
}
}
if(0 == fork_result)
{
close(file_pipes[1]);
//close(file_pipes[0]); //关闭读端,写端调用write时会接收到SIGPIPE信号,默认动作是进程异常终止。
//若写端忽略阻止了该信号,则 write返回-1,errno为EPIPE错误
printf("in child process ");
data_processed = read(file_pipes[0],buffer,BUFSIZ);
printf("read %d bytes:%s ",data_processed,buffer);
close(file_pipes[0]);
printf("read exit ");
}
else
{
signal(SIGPIPE,SIG_IGN);
close(file_pipes[0]);
//close(file_pipes[1]);// 关闭写端,则读端调用read时返回0字节
printf("in parent process ");
data_processed = write(file_pipes[1],some_data,strlen(some_data));
printf("wrote %d bytes ",data_processed);
if(-1 == data_processed)
{
printf("errno:%d ",errno);
if( EPIPE == errno)
printf("vvvvvvvvvv");
}
close(file_pipes[1]);
printf("write exit");
}
return 0;
}
阅读(942) | 评论(0) | 转发(0) |