无名管道读写特点|学习笔记

简介: 快速学习无名管道读写特点

开发者学堂课程【物联网开发- Linux 高级程序设计全套视频无名管道读写特点 】学习笔记,与课程紧密联系,让用户快速学习知识。

课程地址:https://developer.aliyun.com/learning/course/660/detail/11028


无名管道读写特点

 

内容介绍

一、从管道中读写数据的特点

二、验证一

三、验证四

四、验证三

 

一、从管道中读写数据的特点

1、默认用read函数从管道中读数据是阻塞的

在读数据的过程中,若无名管道内无数据,就会停在读;待有数据后继续执行。

2、调用write函数向管道里写数据,当缓冲区已满时write也会阻塞。

当管道满了之后,就会停在当前的位置;有空间后继续执行

3、通信过程中,读端口全部关闭后,写进程向管道内写数据时,写进程会(收到SIGPIPE)退出

父进程创建一个子进程,若父子进程都将读端关闭,则没有进程在读东西。

编程时我们可以设置阻塞非阻塞(read默认阻塞,write也是阻塞的)

看一下其中的特点

编程时可通过fcntl函数设置文件的阻塞特性

设置为阻塞:

Fcntl(fd,F-setfl,0);

设置非阻塞:

Fcntl(fd,-setfl,O-NONBLOCK);

(将读端或者写端的文件描述符写入,NONBLOCK指非阻塞)

如果将读端设置为非阻塞,没有数据的时候也不会阻塞;

如果将写端设置为非阻塞,写满了就不能再写,但不会阻塞。

 

二、验证一

来看一个例子:

验证无名管道文件读写的阻塞和非阻塞

(我们只写一句话,之后不停的对此进行读取,如果没有数据,那么read就会带阻塞)

#include <stdio.h>

#include‹string.h>

#include<unistd.h>

#include‹stdlib.h>

#include <sys/twpes.h>

#include<sys/wait.h>

#include <fcntl.h>

注意需要包括以上图文件

int main (int argc, char *argv[])

int fd pipe[2];

首先我们定义一个数组,用来作为管道的读写端号

char buf[]=“hello world ”(定义一个字符数组,存放hello world;注意 buf是12个字节,)

pid_t pid;

首先进来需要创建管道,然后管道的读端和写端保存在数组里面

if (pipe (fd pipe) < 0)

perror ("pipe") ;

pid=fork();(创建子进程)

if (pid< 0)

{

perror ("fork") ;

exit (-1);

}

if (pid==0)

{

Sleep(3);(3秒之后write)

write(fd_pipe[1],buf,strlen(buf)) ;(strlen测试写了多少个字节进去)

_exit (0) ;

}

else

{

//fcntl(fd_pipe[0],F_SETFL,O_NONBLOCK);

fcntl设置管道的读端,默认第三个数据传0是阻塞的

fcntl (fd pipe[0], F_SETFL, 0) ;

while (1)(循环)

{

memset (buf, 0, sizeof (buf)) ;(先清空buf)

read (fd pipe[0], buf,sizeof (buf) ) ;(从管道的读端开始读东西)

print ("buf=[%s] \n", buf) ;(3秒后读到数据打印出来)

sleep (1) ;

延时1秒再去读,但是子进程已经退出,父进程一直阻塞在read上

}

}

Return 0;

 

三、验证二

调用 write 函数向管道里写数据,当缓冲区已满时write也会阻塞(在管道中写数据,如果写满了write在阻塞)。

更改进程:

父进程只读一次(读到之后打印出来),在while循环上。

子进程while(1)在不断的输入内容,每写完一次都i++,printf(“i=%d\n”,d)

此管道早晚都会被子进程写满,写满之后write堵塞,i就不打印了。

 

四、验证三

通信过程中,读端口全部关闭后,写进程向管道内写数据时,写进程会(收到SIGPIPE)退出

image.png

更改进程:

父进程先去读一次数据,之后close(fd-pipe[0]);//关闭读端

子进程也需要关闭读端,之后循环write;一秒钟写一次;读不到数据就一直停在当前。

需要将所有的读端关掉

相关文章
|
3月前
|
Ubuntu Linux
内核实验(八):实现O-NONBLOCK非阻塞读写
本文通过修改之前的内核模块代码,介绍了如何在Linux内核中实现O_NONBLOCK非阻塞读写机制,并通过在Qemu虚拟机上的测试验证了非阻塞读写操作的正确性。
58 0
内核实验(八):实现O-NONBLOCK非阻塞读写
|
5月前
|
存储 安全 Python
进程通信 , 信号量 , 队列 , 管道 , 共享内存
进程通信 , 信号量 , 队列 , 管道 , 共享内存
|
5月前
|
API 内存技术
无名管道&&有名管道详解代码
无名管道&&有名管道详解代码
|
6月前
|
负载均衡 Java Linux
管道,信号量,共享内存,socket的实际使用场景和NSPipe管道的使用
管道,信号量,共享内存,socket的实际使用场景和NSPipe管道的使用
89 0
|
6月前
内存映射实现无血缘关系进程间通信
内存映射实现无血缘关系进程间通信
|
6月前
|
Linux
进程通信——共享内存
进程通信——共享内存
98 0
|
11月前
|
消息中间件 Unix Linux
【Linux学习】进程间通信的方式(匿名管道、命名管道、共享内存)1
【Linux学习】进程间通信的方式(匿名管道、命名管道、共享内存)
449 0
|
11月前
|
存储 消息中间件 监控
【Linux学习】进程间通信的方式(匿名管道、命名管道、共享内存)2
【Linux学习】进程间通信的方式(匿名管道、命名管道、共享内存)
75 0
|
消息中间件 Unix Linux
进程间通信之管道(匿名管道与命名管道)
首先我们先提出一个问题:进程之间为什么无法直接通信,而需要操作系统提供通信方式: 经过我们上一个博客学习我们可以知道,每个进程都有独立的虚拟地址空间,一个进程在访问一个数据的时候都是通过地址来进行访问的,进过页表映射在之后访问物理内存,因此如果想要给另一个进程传递一个数据,就要把它的地址空间传递给其他进程,因为a进程的是虚拟地址,所以b进程经过页表映射也访问不了。(这个设计的初衷是:独立虚拟空间可以更稳定)
372 0
|
物联网 Linux 开发者
无名管道的创建|学习笔记
快速学习无名管道的创建
无名管道的创建|学习笔记