大家好,又见面了,我是你们的朋友全栈君。
试验目的:
1、向管道写端写入数据前,关闭管道写端fd,errno值会是什么?
2、向管道写端写入数据后,关闭管道写端fd,从管道读端读取数据时,是否能正常读取数据?
3、向管道写端写入数据后,关闭管道读端fd,从管道读端读取数据时,会发生什么?errno是什么?
4、向管道写端写入输入前,关闭管道读端fd,是否会触发SIGPIPE信号?程序如何不崩溃?errno值是否会为EPIPE?
正常代码流程:
1、创建一个管道pipefd[2]
2、向管道写端pipefd[1]写入数据
3、从管道读端pipefd[0]读取数据
4、正常关闭管道写端和读端
试验结果:
1、errno=8, 写端fd报:Bad file descriptor。不会触发SIGPIPE, errno也不会为EPIPE
2、可以正常读取到写入的数据
3、和1情况一样。errno=8, 读端fd报:Bad file descriptor。不会触发SIGPIPE, errno也不会为EPIPE
4、会触发SIGPIPE。
如果程序不处理SIGPIPE或者按照默认方式处理SIGPIPE,则程序会退出。
如果忽略SIGPIPE( 使用signal(SIGPIPE, SIG_IGN); ),则程序不会因为系统触发SIGPIPE而退出,会继续执行完。
在向管道写端写入数据时,errno=8, 为EPIPE, 报:Broken pipe
结论:
1、程序中忽略 SIGPIPE信号。
2、向管道写端写入数据时,可以检测errno是否为EPIPE,如果是,可以关闭管道写端fd。
代码:
代码语言:javascript复制/*
* pipe_op.c
*
* Created on: Jun 24, 2014
* Author: lingyun
*/
#include "pipe_op.h"
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <assert.h>
#include <stdio.h>
#include <errno.h>
#include <fcntl.h>
#include <bits/signum.h>
#include <signal.h>
#define BUFFER_SIZE 1024
void
pipe_create(int pipefd[2]) {
int ret;
ret = socketpair(PF_UNIX, SOCK_STREAM, 0, pipefd);
assert(ret != -1);
}
void
pipe_close(int pipefd) {
if (pipefd > 0) {
close(pipefd);
}
}
void
pipe_func_test() {
//忽略SIGPIP信号
signal(SIGPIPE, SIG_IGN);
//按照默认处理方式处理SIGPIP信号
//signal(SIGPIPE, SIG_DFL);
int pipefd[2];
pipe_create(pipefd);
int pipe_read_fd = pipefd[0];
int pipe_write_fd = pipefd[1];
printf("pipe read end: %dn", pipe_read_fd);
printf("pipe write end: %dn", pipe_write_fd);
//write msg to write_pipe, and read from read_pipe
char buf[BUFFER_SIZE];
memset(buf, '