谷歌云 阿里云 做网站,深圳商业网站建设哪家专业,制作网站的程序语言,电子商务网站建设 实验分析管道的读写特点#xff1a;
使用管道时#xff0c;需要注意以下几种特殊的情况#xff08;假设都是阻塞I/O操作#xff09;
1.所有的指向管道写端的文件描述符都关闭了#xff08;管道写端引用计数为0#xff09;#xff0c;有进程从管道的读端
读数据#xff0c;那么管…管道的读写特点
使用管道时需要注意以下几种特殊的情况假设都是阻塞I/O操作
1.所有的指向管道写端的文件描述符都关闭了管道写端引用计数为0有进程从管道的读端
读数据那么管道中剩余的数据被读取以后再次read会返回0就像读到文件末尾一样。2.如果有指向管道写端的文件描述符没有关闭管道的写端引用计数大于0而持有管道写端的进程
也没有往管道中写数据这个时候有进程从管道中读取数据那么管道中剩余的数据被读取后
再次read会阻塞直到管道中有数据可以读了才读取数据并返回。3.如果所有指向管道读端的文件描述符都关闭了管道的读端引用计数为0这个时候有进程
向管道中写数据那么该进程会收到一个信号SIGPIPE, 通常会导致进程异常终止。4.如果有指向管道读端的文件描述符没有关闭管道的读端引用计数大于0而持有管道读端的进程
也没有从管道中读数据这时有进程向管道中写数据那么在管道被写满的时候再次write会阻塞
直到管道中有空位置才能再次写入数据并返回。总结读管道管道中有数据read返回实际读到的字节数。管道中无数据写端被全部关闭read返回0相当于读到文件的末尾写端没有完全关闭read阻塞等待写管道管道读端全部被关闭进程异常终止进程收到SIGPIPE信号管道读端没有全部关闭管道已满write阻塞管道没有满write将数据写入并返回实际写入的字节数
#include unistd.h
#include sys/types.h
#include stdio.h
#include stdlib.h
#include string.h
#include fcntl.h
/*设置管道非阻塞int flags fcntl(fd[0], F_GETFL); // 获取原来的flagflags | O_NONBLOCK; // 修改flag的值fcntl(fd[0], F_SETFL, flags); // 设置新的flag
*/
int main() {// 在fork之前创建管道int pipefd[2];int ret pipe(pipefd);if(ret -1) {perror(pipe);exit(0);}// 创建子进程pid_t pid fork();if(pid 0) {// 父进程printf(i am parent process, pid : %d\n, getpid());// 关闭写端close(pipefd[1]);// 从管道的读取端读取数据char buf[1024] {0};int flags fcntl(pipefd[0], F_GETFL); // 获取原来的flagflags | O_NONBLOCK; // 修改flag的值fcntl(pipefd[0], F_SETFL, flags); // 设置新的flagwhile(1) {int len read(pipefd[0], buf, sizeof(buf));printf(len : %d\n, len);printf(parent recv : %s, pid : %d\n, buf, getpid());memset(buf, 0, 1024);sleep(1);}} else if(pid 0){// 子进程printf(i am child process, pid : %d\n, getpid());// 关闭读端close(pipefd[0]);char buf[1024] {0};while(1) {// 向管道中写入数据char * str hello,i am child;write(pipefd[1], str, strlen(str));sleep(5);}}return 0;
}