在Linux中,该缓冲区的大小为1页,即4K字节,使得它的大小不象文件那样不加检验地增长。...使用单个固定缓冲区也会带来问题,比如在写管道时可能变满,当这种情况发生时,随后对管道的write()调用将默认地被阻塞,等待某些数据被读取,以便腾出足够的空间供write()调用写。...读取进程也可能工作得比写进程快。当所有当前进程数据已被读取时,管道变空。当这种情况发生时,一个随后的read()调用将默认地被阻塞,等待某些数据被写入,这解决了read()调用返回文件结束的问题。...当写进程向管道中写入时,它利用标准的库函数write(),系统根据库函数传递的文件描述符,可找到该文件的 file 结构。...当数据写入内存之后,内存被解锁,而所有休眠在索引节点的读取进程会被唤 醒。 管 道的读取过程和写入过程类似。
实际上,管道是一个固定大小的缓冲区。在Linux中,该缓冲区的大小为1页,即4K字节,使得它的大小不象文件那样不加检验地增长。...· 读取进程也可能工作得比写进程快。当所有当前进程数据已被读取时,管道变空。...当写进程向管道中写入时,它利用标准的库函数write(),系统根据库函数传递的文件描述符,可找到该文件的 file 结构。...当数据写入内存之后,内存被解锁,而所有休眠在索引节点的读取进程会被唤 醒。 管 道的读取过程和写入过程类似。...Linux 还支持命名管道。对这些数字的早期评论员建议我,为公平起见,应该比较 Linux 的命名管道和 Windows 的命名管道。我写了另一个在 Linux 上使用命名管道的程序。
下面我们验证如果管道被写满,会发生什么情况 所以我们在父进程中先让父进程休眠一段时间,并在子进程中打印 number,观察写端写满管道后会发生什么情况: // 父进程读取 void Read...也就是说,当子进程向管道写满了,当父进程在读的时候,就会把多次写的信息一次读了出来,在父进程看来,它读到的就是一个一个的字符,对于我们用户用什么存取,如何区分,这是我们用户的事。...当父进程没有向管道里写内容时,对应的子进程就会阻塞等待父进程派任务,一旦父进程向管道中写了,子进程会读取对应的数据然后继续向后执行,结合读取的数据就可以执行对应的任务了。...接下来我们规定,父进程向子进程管道里写的,都叫做任务码,也就是,我们规定好父子通信时,父进程每次写入时,只能写入4字节,子进程在读取时,也只能读取4字节。...观察现象: 如上图,当写端进行写入的时候,命令行会变成一个进程,向管道里写入,此时读端没有读取,所以写端正在阻塞。当读端进行读取后: 此时左侧的字符串会到了右侧。
进程间通信 1.1. 进程间通信的目的 1.2. 如何实现进程间通信 2. 管道通信 2.1. 匿名管道 2.1.1 创建匿名管道 2.1.2 . 深入理解匿名管道 2.2. 命名管道 2.2.1....因为管道是面向字节流的,字符串之间没由规矩分隔符,如果读取速度慢于写入速度,可能读端还没有将整个字符串读完,写端又写入了数据,会导致数据混乱。 2.1.2 ....64KB,写端写满后不会再写,会等读端读取管道内容,且读取4KB后才会重新写入(读端的容量为4KB)。...命名管道 为了解决匿名管道只能在父子进程间通信的缺陷,引入了命名管道。...创建命名管道 命令行创建 使用命令 mkfifo 管道 然后使用一个简单的shell脚本,将 hello world 每间隔一秒输入到管道中,然后另一边读取管道中的内容。
信号量Semaphore:信号量是一个计数器,可以用来控制多个进程对共享资源的访问。它常作为一种锁机制,防止某进程正在访问共享资源时,其他进程也访问该资源。...管道的实质是一个内核缓冲区,进程以先进先出的方式从缓冲区存取数据:管道一端的进程顺序地将进程数据写入缓冲区,另一端的进程则顺序地读取数据,该缓冲区可以看做一个循环队列,读和写的位置都是自动增加的,一个数据只能被读一次...用户进程可以向消息队列添加消息,也可以向消息队列读取消息。 消息队列与管道通信相比,其优势是对每个消息指定特定的消息类型,接收的时候不需要按照队列次序,而是可以根据自定义条件接收特定类型的消息。...对消息队列有写权限的进程可以向消息队列中按照一定的规则添加新消息,对消息队列有读权限的进程可以从消息队列中读取消息。...而可以取多个正整数的信号量被称为通用信号量。 Linux 下的信号量函数都是在通用的信号量数组上进行操作,而不是在一个单一的二值信号量上进行操作。
当写进程向管道中写入时,它利用标准的库函数write(),系统根据库函数传递的文件描述符,可找到该文件的 file 结构。...当数据写入内存之后,内存被解锁,而所有休眠在索引节点的读取进程会被唤醒。 管道的读取过程和写入过程类似。...]); filedes[1]用于写入数据,写入时必须关闭读取端,即close(filedes[0])。...写模式的进程向FIFO文件中写入,而读模式的进程从FIFO文件中读出。 当删除FIFO文件时,管道连接也随之消失。...FIFO读写规则 1.从FIFO中读取数据:约定:如果一个进程为了从FIFO中读取数据而阻塞打开了FIFO,那么称该进程内的读操作为设置了阻塞标志的读操作 2.从FIFO中写入数据:约定:如果一个进程为了向
信号量Semaphore:信号量是一个计数器,可以用来控制多个进程对共享资源的访问。它常作为一种锁机制,防止某进程正在访问共享资源时,其他进程也访问该资源。...管道的实质是一个内核缓冲区,进程以先进先出的方式从缓冲区存取数据:管道一端的进程顺序地将进程数据写入缓冲区,另一端的进程则顺序地读取数据,该缓冲区可以看做一个循环队列,读和写的位置都是自动增加的,一个数据只能被读一次...例子:用命名管道实现聊天程序,一个张三端,一个李四端。两个程序都建立两个命名管道,fifo1,fifo2,张三写fifo1,李四读fifo1;李四写fifo2,张三读fifo2。...用户进程可以向消息队列添加消息,也可以向消息队列读取消息。 消息队列与管道通信相比,其优势是对每个消息指定特定的消息类型,接收的时候不需要按照队列次序,而是可以根据自定义条件接收特定类型的消息。...对消息队列有写权限的进程可以向消息队列中按照一定的规则添加新消息,对消息队列有读权限的进程可以从消息队列中读取消息。
同理,命名管道文件也是如此,先创建出文件,在文件系统中挂个名,然后让独立的进程以不同的方式打开同一个命名管道文件,比如进程 A 以只读的方式打开,进程 B 以只写的方式打开,那么此时进程 B 就可以向进程...《Linux进程间通信【匿名管道】》 2.1、特点 可以简单总结为: 管道是半双工通信 管道生命随进程而终止 命名管道任意多个进程间通信 管道提供的是流式数据传输服务 管道自带 同步与互斥 机制 2.2...注意: 创建管道文件后,无论先启动读端,还是先启动写端,都要阻塞式的等待另一方进行交互 3.2、实现进程控制 在 Linux 匿名管道 IPC 中,我们实现了一个简易版的进程控制程序,原理是通过多条匿名管道实现父进程对多个子进程执行任务分配...0; } 执行结果如下: 关于 父子进程间使用命名管道通信 值得注意的问题: 在命名管道创建后,需要先创建子进程,让子进程打开【读端或写端】,然后才让父进程打开【写端或读端】,这是因为假如先让父进程打开...,不过二者在创建和打开方式上各有不同:匿名管道简单,但只能用于具有血缘关系进程间通信,命名管道虽麻烦些,但适用于所有进程间通信场景;在本文的最后,使用命名管道实现了几个简单的小程序,这些小程序的本质都是一样的
进程间通信介绍 进程间通信目的 数据传输:一个进程需要将它的数据发送给另一个进程。 资源共享:多个进程之间共享同样的资源。...用例:从键盘读取数据,写入管道,读取管道,写到屏幕 #include #include #include #include <unistd.h...管道提供流式服务 一般而言,进程退出,管道释放,所以管道的生命周期随进程 一般而言,内核会对管道操作进行同步与互斥 管道是半双工的,数据只能向一个方向流动;需要双方通信时,需要建立起两个管道 ?...命名管道 管道应用的一个限制就是只能在具有共同祖先的进程间通信。 如果我们想在不相关的进程之间交换数据,可以使用FIFO文件来做这项工作,它经常被称为命名管道。...命名管道的打开规则 如果当前打开操作是为读而打开FIFO时 O_NONBLOCK disable:阻塞直到有相应进程为写而打开该FIFO O_NONBLOCK enable:立刻返回成功 如果当前打开操作是为写而打开
,父进程可以向对应的文件的文件缓冲区写入,子进程可以通过文件缓冲区读取,此时就完成了进程间通信,这种方式提供的文件称为管道文件。...,在写会阻塞,等对方进行读取 write(fds[1],buffer,strlen(buffer));//系统接口 sleep(1);//一秒写一次...: 1.读快写慢 子进程休眠时,不在写入,父进程在读取(如果管道中没有数据,读端在读,此时默认会直接阻塞当前正在读取的进程) 2.读慢写快 拿着管道读端不读,写端一直在写:写端往管道里写,而管道是有大小的...此时写端会阻塞。 如果父进程只是sleep(2),稍微睡眠比较少: 在这里不断读取的时候:写端是把数据塞到管道里,管道读取的是按照指定大小读取!而不是一行一行。...3.写入关闭,读到0 子进程写入端关闭: 4.读取关闭,写入 管道是单向的:读端关闭,在写入就没有意义了:OS会终止写端,会给写进程发送信号,终止写端 管道特征 1.管道的生命周期随进程,进程退出
实现子进程写入,父进程读取 代码示例 子进程向父进程写入“hello i am your child !”...当然,这种命名管道也遵循管道通信的四大现象,比如假如我将读端关闭,那么此时写端进程就成了无意义的写入,OS不会进行维护,就会就发送13号信号,终止写端进程。...); 命名管道打开规则 如果当前打开操作是为读而打开 FIFO 时 O_NONBLOCK disable :阻塞直到有相应进程为写而打开该 FIFO O_NONBLOCK enable...同样,假如A以写的方式打开命名管道,此时A也会进入阻塞,直到B进程以读的方式打开管道文件,A才继续运行。...这里简单的写一个,如下: 此时当我们两个进程都运行时,一方写入,一方读取,实现通信: 当然,这里只是简单的实现通信,我们还可以在共享内存中加入管道,用来控制进程,当客户端写入完成后,服务端再进行读取
所以父子进程有一份公共的资源:文件系统提供的内核缓冲区,父进程可以向对应的文件的文件缓冲区写入,子进程可以在对应的文件缓冲区读取,这样就可以完成进程间通信。...父进程创建子进程,子进程继承管道以及对管道的读写 父进程关闭读取端,子进程关闭写入端。自此父进程只能向管道中写入,子进程只能从管道中读取,完成了父子进程的单向通讯。...2.管道分类 管道根据是否具有文件名,分为匿名管道和有名管道。 1.匿名管道 通过父进程创建子进程,子进程继承文件地址的方式,让父子进程看到同一个内存级文件,该内存级文件没有名称,则就称为匿名管道。...48 return 0; 49 } 2.读慢写快 读取管道的进程一直不进行读取,而写端一直在写入。...写端可以向管道内写入,但是管道是固定大小的缓冲区,不断的只写不读管道会被写满。满了以后就不能再写入了,此时写端会处于阻塞状态。
: close(pipeFDs[ReadEnd]); /* called in parent code */ 然后父进程将向无名管道中写入某些字节数据(ASCII 代码),子进程读取这些数据,然后向标准输出中回放它们...假如两个进程向相同的无名管道中写入内容,字节数据会交错吗?...命名管道 无名管道没有备份文件:系统将维持一个内存缓存来将字节数据从写方传给读方。一旦写方和读方终止,这个缓存将会被回收,进而无名管道消失。相反的,命名管道有备份文件和一个不同的 API。...有一个名为 mkfifo 的库函数,用它可以在程序中创建一个命名管道,它将在下一个示例中被用到,该示例由两个进程组成:一个向命名管道写入,而另一个从该管道读取。...输出也显示消息队列是持久的,即便 sender 进程在完成创建队列、向队列写数据、然后退出的整个过程后,该队列仍然存在。
管道是最早出现的进程间通信的手段,在shell中执行命令,经常会将上一个命令的输出作为下一个命令的输入,由多个命令配合完成一件事情。...如果多个进程发送的字节流混在一起,则无法辨认出各自的内容。所以一般是两个有亲缘关系的进程用管道来通信。 一般来讲,进程中数据流是单向的,并且是阅后即焚的。...如果所有读取端描述符都已关闭,此时进程再次往管道里面写入数据,写操作会失败,errno被设置为EPIPE,同时内核会向写入进程发送一个SIGPIPE的信号。...因此在使用管道的过程中要注意写入数据是否能及时消费的问题,一旦管道满了,写入就会被阻塞;对于读取端,要及时地读取,防止管道被写满,造成写入阻塞。...创建命名管道函数如下: int mkfifo(const char *pathname, modt_t mode) 命名管道支持的管道操作和匿名管道是一样的,只不过它多了一个关联文件,有文件名,这样任何进程通过文件名来使用它而已
我们可以让父进程创建出多个子进程,通过打开多个对应的管道文件和每个子进程建立通信的前提,然后我们可以通过管道的读写规则其中的一条,也就是当写入端写入很慢时,读取端进行阻塞等待。...在创建子进程的过程中,我们需要维护子进程的pid以及管道的写端,为了更好的分清是哪个子进程在执行任务,我们还可以多维护子进程的name,以上这些我们可以写一个类来封装实现,这个类命名为subEndPoint...所以在写代码时,我们常用unlink和mkfifo配合使用来实现命名管道。 mkfifo的参数也好理解,即在pathname路径下创建指定名称的管道文件,并设置管道文件的权限。...第二个细节:键盘输入时多输入了\n回车,这样在写入到管道中的数据末尾会多一个\n字符,server读取进行打印的时候,如果多输出了endl,则输出到显示器上的结果会多一个空行,所以在写入的时候,我们可以将...如果想要让共享内存能够进行同步与互斥,我们可以让管道和共享内存配合起来进行IPC,进程1向共享内存写入数据后,再随便向pipe写一个字符或者其他东西,什么都可以。
IPC(Inter process communication),进程间通信就是在不同进程之间传播或交换信息 进程间通信目的: 数据传输:一个进程需要将它的数据发送给另一个进程 资源共享:多个进程之间共享同样的资源...,并能够及时知道它的状态改变 进程间通信本质:让不同的进程看到同一份资源 由于进程之间具有独立性,代码数据独立拥有,若想实现通信,可以通过向第三方资源(实际上就是操作系统提供的一段内存区域)写入或是读取数据...: 对于同个文件可以以读方式和以写方式打开,文件在文件系统虽然只有一份,但是在进程的PCB中的文件结构体中的文件地址数组中可以保存两份,一份指向文件的读端口,一份指向文件的写端口 管道通过系统接口创建管道文件资源...所以管道的生命周期随进程内核会对管道操作进行同步与互斥,即保证数据的原子性 管道是半双工的,数据只能向一个方向流动;需要双方通信时,需要建立起两个管道 示图: 2、命名管道 概念: 对于匿名管道应用的一个限制就是只能在具有共同祖先...disable:阻塞直到有相应进程为写而打开该FIFO O_NONBLOCK enable:立刻返回成功 如果当前打开操作是为写而打开FIFO时 O_NONBLOCK disable:阻塞直到有相应进程为读而打开该
二.详解 管道文件 管道分为匿名管道和命名管道。管道都是一端写入、另一端读取,它们是单方向数据传输的,它们的数据都是直接在内存中传输的,管道是进程间通信的一种方式,例如父进程写,子进程读。...在shell中匿名管道就是一个管道符号”|”,例如ls | grep xxx,其中ls对应的进程是这个独立进程组中的父进程,grep对应的进程是子进程,父进程写子进程读。...在shell中,可以使用mknod命令或mkfifo命令创建命名管道,在写某些特殊需求的shell脚本时,命名管道非常有用。...进程1向A写入数据,将自动推送到B上,进程2可从B上读取从A写入的数据,同理进程2向B中写入数据将自动推送到A上,进程1可从A上读取从B写入的数据。...进程1向自己的套接字的send buffer写入数据,将发送到对端的recv buffer中,然后对端的进程2就可以从recv buffer中读取数据,反之亦然。
写快读慢当我让子进程取消睡眠,一直往管道文件里写时,父进程睡眠1000秒即一直睡眠不读取管道里的数据图片可以看到打印计数器几百次即子进程一直在写,而父进程没有读取管道文件里是数据,子进程(写端)直至写满管道文件才停止图片而当父进程睡眠两秒时...,即子进程一直往管道文件里写,父进程间隔性读取数据,间隔时间为2秒图片图片可以看到写端是一直往管道文件里写,而读端并不是一次读取一个字符串,而是一次读取read规定的大小字节数。...,导致子进程异常退出,退出码是13,查表得知是SIGPIPE;即当操作系统知道有写端非法写入时,会发送13号信号码给该进程强制杀死写端。...,命令行是一个进程,cat将数据读出也是一个进程,数据在一个进程流通到另一个进程,命名管道也完成了进程间通信!...消息按顺序插入队列中,其中发送进程将消息添加到队列末尾,接收进程从队列头读取消息。多个进程可同时向一个消息队列发送消息,也可以同时从一个消息队列中接收消息。
管道是一种半双工的通信方式,数据只能单向流动,但是无名管道和有名管道的区别是无名管道只能在具有亲缘关系的进程间通信,有名管道则是在无亲缘关系进程间通信。进程的亲缘关系通常是指父子进程关系。...当一个进程向管道中写的内容被管道另一端的进程读出;写入的内容每次都会被添加到管道缓冲区的末尾,并且每次都是从缓冲区的头部读出数据。如下图所示。 ? 那么,如何创建一条管道呢?...FIFO比pipe函数打开的时候多了一个打开操作open;如果当时打开操作时为读而打开FIFO时,若已经有相应进程为写而打开该FIFO,则当前打开操作将返回成功;否则,可能阻塞到有相应进程为写而打开该FIFO...另一种情况就是为写而打开FIFO时,若已经有相应进程为读而打开该FIFO,则当前打开操作将成功返回;否则可能会阻塞直到有相应进程为读而打开该FIFO;或者,返回ENIO错误。...下面我们使用FIFO实现进程间的通信。 (1)打开一个文件,管道的写入端向文件写入数据;管道的读取端从文件中读取出数据。
命名管道基础 命名管道也被称为FIFO文件, 在文件系统中是可见的,并且跟其它文件一样可以读写!...命名管道特点: 当写进程向管道中写数据的时候,如果没有进程读取这些数据,写进程会堵塞 当读取管道中的数据的时候,如果没有数据,读取进程会被堵塞 当写进程堵塞的时候,有读进程读取数据,那么写进程恢复正常...当读进程堵塞的时候,如果写进程写了数据,那么读进程会读取数据,然后正常执行后面的代码 # 写进程堵塞的情况 [root@ns_10.2.1.242 test]$ echo 1 >p & [1]...创建管道的命令: $ mkfifo /tmp/testpipe $ mknod /tmp/testpipe p 下面是命名管道的一个应用例子: reader.sh读取管道的内容,代码如下: #!...break else echo $line fi fi done echo "Stop reader...." writer.sh写数据到管道
领取专属 10元无门槛券
手把手带您无忧上云