首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

【Linux】进程间通信 --- 管道 共享内存 消息队列 信号量

写端关闭文件描述符后,读端读取到的字节数为0,也就是一个EOF信号,表示读端已经读到文件结尾了。由于写端文件描述符已经被关闭,则不可能有新的数据再写入。...写入端是主动的,读取端是被动的,当没有进程读取的时候,写入端作为主动的一方肯定不会傻傻的等着,此时OS会给写进程发信号来终止写端进程。...当父进程向某个子进程发送command code时,也就是对应的命令码,每个命令码对应一个需要子进程完成的任务,当父进程没发送command code的时候,其他未接收到命令码的子进程则一直进行阻塞等待即可...这里容易混淆的一个点是,只有当一个管道的所有wfd关闭之后,读端才会读到0,也就是EOF文件结尾信号。...如果想要让共享内存能够进行同步与互斥,我们可以让管道和共享内存配合起来进行IPC,进程1向共享内存写入数据后,再随便向pipe写一个字符或者其他东西,什么都可以。

1.5K40

Linux进程间通信--管道(pipe和fifo)

假如说我们现在有一根管道,我们从左端放入一个小球,那么它会从右端滚出来,那么如果我们同时向两端都放入一个小球,那么就不可能实现交叉传递了,所以管道是半双工通信(即双方都可以发送信息,但是双方不能同时发送信息...当管道写端关闭时,读端读完管道内的数据时,如果再次去读没有数据的管道会返回0,相当于读到了EOF。           4....当管道读端关闭时,如果写端在写入数据时,产生SIGPIPE信号,写进程默认情况下会终止进程。        ...// 关闭读端 sleep(5); write(fd[1], buf, strlen(buf)); // 在写端写入buf中的数据...因为这个管道有一个所有进程都可以访问到的管道文件,所以fifo叫做命名管道,那么同理,pipe就只能通过fork的方式来复制文件描述符表来共享管道,而其他的进程却访问不到,所以叫做匿名管道。

3.8K30
  • 您找到你想要的搜索结果了吗?
    是的
    没有找到

    Linux管道那些事儿

    如果多个进程发送的字节流混在一起,则无法辨认出各自的内容。所以一般是两个有亲缘关系的进程用管道来通信。 一般来讲,进程中数据流是单向的,并且是阅后即焚的。...管道有如下3个特性: 只有当所有的写入端描述符都已关闭,且管道中的数据都被读出,对读取端描述符调用read函数才会返回0(即读到EOF标志)。...如果所有读取端描述符都已关闭,此时进程再次往管道里面写入数据,写操作会失败,errno被设置为EPIPE,同时内核会向写入进程发送一个SIGPIPE的信号。...当所有的读取端和写入端都关闭后,管道才能被销毁。 管道的本质是一片内存区域,默认大小是65536字节,不过可以调用fcntl来获取和修改这个值的大小。...因此在使用管道的过程中要注意写入数据是否能及时消费的问题,一旦管道满了,写入就会被阻塞;对于读取端,要及时地读取,防止管道被写满,造成写入阻塞。

    2.7K50

    Linux 下的进程间通信:使用管道和消息队列

    管道拥有一个写端用于写入字节数据,还有一个读端用于按照先入先出的顺序读入这些字节数据。而这些字节数据可能代表任何东西:数字、员工记录、数字电影等等。...在上面的例子中,sleep 进程并没有向通道写入任何的字节数据,但在 5 秒后就终止了,这时将向通道发送一个流已终止的标志。...在 if 子句中的第一个语句将用于关闭管道的读端: close(pipeFDs[WriteEnd]); /* called in child code */ 在父进程中的 else 子句将会关闭管道的读端...在效果上,子进程会告诉系统立刻去通知父进程它的这个子进程已经终止了。 假如两个进程向相同的无名管道中写入内容,字节数据会交错吗?...例如,假如进程 P1 向管道写入内容: foo bar 同时进程 P2 并发地写入: baz baz 到相同的管道,最后的结果似乎是管道中的内容将会是任意错乱的,例如像这样: baz foo baz bar

    1.2K20

    你所不知道的linux匿名管道知识

    管道的定义 管道是由内核管理的一个缓冲区,相当于我们放入内存中的一个纸条。管道的一端连接一个进程的输出。这个进程会向管道中放入信息。管道的另一端连接一个进程的输入,这个进程取出被放入管道的信息。...,则read返回0 4.如果所有管道读端对应的文件描述符被关闭,则write操作会产生信号SIGPIPE 5.当要写入的数据量不大于PIPE_BUF时,linux将保证写入的原子性。...将读端进程杀掉 输出结果 从上图我们可以验证两个点: 当我们杀掉读端时, 写端会收到SIGPIPE而默认退出, 管道结束 当我们杀掉读端时, 写端的程序并不会马上收到SIGPIPE, 相反的..., 只有真正写入管道写端时才会触发这个错误 如果写入一个 读端已经关闭的管道, 将会收到一个 SIGPIPE, 那读一个写端已经关闭的管道又会这样呢?...在上面也已经证明了上文提到的读写规则: 如果所有管道写端对应的文件描述符被关闭,将产生EOF结束标志,read返回0, 程序退出 总结 通过上面的理论和实验, 我们知道在使用管道时, 两边命令的数据传输过程

    79520

    你所不知道的linux匿名管道知识

    管道的定义 管道是由内核管理的一个缓冲区,相当于我们放入内存中的一个纸条。管道的一端连接一个进程的输出。这个进程会向管道中放入信息。管道的另一端连接一个进程的输入,这个进程取出被放入管道的信息。...,则read返回0 4.如果所有管道读端对应的文件描述符被关闭,则write操作会产生信号SIGPIPE 5.当要写入的数据量不大于PIPE_BUF时,linux将保证写入的原子性。...将读端进程杀掉 输出结果 从上图我们可以验证两个点: 当我们杀掉读端时, 写端会收到SIGPIPE而默认退出, 管道结束 当我们杀掉读端时, 写端的程序并不会马上收到SIGPIPE, 相反的,...只有真正写入管道写端时才会触发这个错误 如果写入一个 读端已经关闭的管道, 将会收到一个 SIGPIPE, 那读一个写端已经关闭的管道又会这样呢?...在上面也已经证明了上文提到的读写规则: 如果所有管道写端对应的文件描述符被关闭,将产生EOF结束标志,read返回0, 程序退出 总结 通过上面的理论和实验, 我们知道在使用管道时, 两边命令的数据传输过程

    1.3K50

    故障分析 | Redis AOF 重写源码分析

    子进程 关闭监听socket,避免接收客户端连接 设置进程名 生成AOF临时文件名 遍历每个数据库的每个键值对,以插入(命令+键值对)的方式写到临时AOF⽂件中 父进程 计算上一次fork已经花费的时间...children -> parent ack发送ACK信号 在完成⽇志重写,以及多次向⽗进程读取操作命令后,向children -> parent ack发送"!"...2.CPU开销 在AOF重写期间主进程需要花费CPU时间向aof_rewrite_buf写数据,并使用eventloop事件循环向子进程发送aof_rewrite_buf中的数据。...//创建事件以便向子进程发送数据 if (!...AOF重写操作的后期,会循环读取pipe中主进程发送来的增量数据,然后追加写入到临时AOF文件。

    87320

    【linux学习指南】 进程间通信&&匿名管道&&理解管道的本质

    进程间通信发展 管道(Pipe): 管道是最早的进程间通信机制之一。 管道允许一个进程向另一个进程写入数据,另一个进程可以读取数据。 管道是单向的,数据只能在一个方向上流动。...父进程可以向管道的写端 fds[1] 写入数据。 在子进程中: 子进程关闭管道的写端 fds[1]。 子进程可以从管道的读端 fds[0] 读取数据。...进程间通信: 当一个进程向管道的写端 fds[1] 写入数据时,数据会被写入内核缓冲区。 另一个进程可以通过读端 fds[0] 从内核缓冲区中读取数据。 这样就实现了进程间的通信。...关闭文件描述符: 当一个进程不再需要管道的某个端口时,应该关闭相应的文件描述符。 关闭读端 fds[0] 表示不再从管道读取数据,关闭写端 fds[1] 表示不再向管道写入数据。...当写端向管道写入数据时,数据会被存储在缓冲区中。 当读端从管道读取数据时,数据会从缓冲区中取出。 读写机制: 写入管道时,如果缓冲区已满,写进程会被阻塞,直到有空间可写。

    8410

    记一次传递文件句柄引发的血案

    书上讲道:“在技术上,发送进程实际上向接收进程传送一个指向一打开文件表项的指针,该指针被分配存放在接收进程的第一个可用描述符项中。”...它关闭管道的另一端,然后在fork出的子进程中将另一端重定向到子进程的标准输入、输出。...之后不断从console读入用户输入的两个整数,创建一个临时文件(get_temp_fd)并将用户输入写入文件, 之后通过管道将此临时文件传递给子进程,然后在管道上等待子进程返回的另一个临时文件句柄,...这就奇怪了,读取管道返回这个错误的唯一原因只能是管道被关闭,而此管道在子进程端已经被重定向到了标准输入、标准输出, 当标准输入输出关闭时,唯一的可能性是进程已经退出。难道子进程已经不在了么?...一开始怀疑是数据写入后,没有 flush 到磁盘,从而导致另一端没有读到,于是在写入数据之后、发送句柄之前,加了以下代码: if (fsync (fd_to_send) < 0)

    50320

    Unix域协议学习小结

    关闭写管道的读端 ... // 向pipe_out[1]中写数据,并从pipe_in[0]中读结果 close(pipe_out...但是如果向一个套接字(sockfd1)中写入,再从该套接字总读取,就会阻塞,只能够在另一个套接字(sockfd0)中读取 读写可以位于同一个进程,也可以位于不同的进程,如父子进程。...如果需要关闭子进程的输入同时通知子进程数据已经发送完毕,而随后从子进程的输出中读取数据直到遇到EOF,对于之前的pipe创建的单向管道来说不会存在任务问题;但是使用socketpair创建的双向管道时,...如果不关闭管道就无法通知对端数据已经发送完毕,但是关闭了管道又无法送终读取结果数据。...此时可以使用shutdown,来实现一个半关闭操作,通知对端进程不再发送数据,同时仍可以从该文件描述符中把剩余的数据接收完毕,最后再使用close关闭描述符。

    2.1K20

    CSAPP 网络编程 笔记

    而且这里的 read 将不会受到来自其他主机的应答。 如何避免UDP协议下客户端将非服务端发送的应答,误认为是服务器应答?...8.关闭非阻塞状态并返回 I/O 复用 可等待多个描述字的就绪 信号驱动 内核在描述字就绪时,发送 SIGIO 信号通知进程 绑定信号以及对应的处理函数 => 继续执行其他操作 => 满足后自动处理...多播 用途 局域网、跨广域网都可使用 问题 与广播的区别,以及分别的应用场景 广播是向网络中所有主机发送信息 广播由于是向全网发,其他无关主机都会收到,而且要到传输层才能处理,浪费网络、计算资源...有足够的权限的进程可以向队列中添加消息,被赋予读权限的进程可以读取队列中的消息 消息队列克服了信号承载信息量少,管道只能承载无格式字节流以及缓冲区大小受限等特点 消息队列不需要进程间具有亲缘关系 信号与信号量...,如信号量 问题 命名管道、管道的区别 命名管道以 FIFO 的形式存在于文件系统中,与 FIFO 创建进程无亲缘关系的进程只要能访问该路径,就能彼此通信 管道在最后一个关闭后自动消失,而 FIFO 需要通过

    58030

    Linux:进程间通信(一.初识进程间通信、匿名管道与命名管道、共享内存)

    通知事件:一个进程需要向另一个或一组进程发送消息,通知它们发生了某种事件,如进程终止、资源可用等。通过通知事件,进程可以及时响应和处理其他进程的状态变化,实现进程之间的协作和同步。...内存中的缓冲区:管道实际上是一个在内核中维护的缓冲区,用于存储从写入端发送但尚未被读取端读取的数据。这个缓冲区的大小是有限的,如果写入的数据超过了缓冲区的大小,写操作可能会被阻塞,直到有空间可用。...最后就会读到返回值为0,表示读结束,类似读到了文件的结尾 读端关闭其文件描述符并且不再读取数据时,如果写端继续向管道写入数据,操作系统会发送一个SIGPIPE信号给写端进程。...SIGPIPE信号(信号编号为13)的发送是为了通知写端进程,其写操作因为管道的另一端没有读端而不再有意义。...一个进程可以向命名管道写入数据,另一个进程可以从命名管道读取数据,实现了进程间的数据交换。

    44420

    【Linux】进程通信之管道

    ,即它们会指向相同的文件: 然后我们分别关闭父进程对管道文件的读方式,以及子进程对管道文件的写方式,这时,管道文件就成为了一个由父进程写入数据,子进程读取数据的通信管道文件:...当然也可以关闭父进程对管道文件的写方式,以及子进程对管道文件的读方式,这样管道文件就成为了一个由子进程写入数据,父进程读取数据的通信管道文件。...编码实现父子进程通信管道 管道的实现思路如下: 创建管道 创建子进程, 子进程关闭读端, 然后开始向管道写入数据 父进程关闭写端,然后开始向管道读数据 读取完毕,父子进程关闭自己所使用的写..., 而且这些消息是连续的, 并没有断层, 这说明当管道中数据满了的时候, 写入端(write)是会调用阻塞,暂停进程执行,直到所有数据被读取走后才会继续写入: 验证代码如下: #include...close(pipefd[0]); return 0; } 当管道写端对应的文件描述符被关闭,读端正常时 如果所有管道写端对应的文件描述符被关闭,则read返回0

    13710

    【Linux】进程间通信上 (1.5万字详解)

    结论:当管道中没有数据时,且写端没有关闭写文件描述符时,读端会一直阻塞等待,直到写端有数据写入。 情况3 写端正常写入,读端每10秒钟读取一次数据。当管道被写满时,写端在做什么?...情况4 读端正常读取,写端在写入过程中突然将写文件描述符关闭 总结:当写端不再写入,并且关闭了pipe,那么读端将会把管道内的内容读完,最后就会读到返回值为0,表示读取结束,类似于读到了文件的结尾。...这是因为没有进程从管道读取数据了 ,所以往管道中写入的数据就是没有利用价值的,操作系统不会出现这种毫无价值的写入。 总结:当读端不再进行读取操作,并且关闭自己的文件描述符fd,此时的写就没有意义了。...所以我们: 所以,的确是操作系统向子进程发送13号信号,来终止写进程的。 根据管道的几种特殊读写的情况,也间接创造出了管道的5个特征。...fifo,但它仅仅是一种符号,那么对于这种符号呢,将来你向这个文件里写入的消息,并没有或者并不会刷新落实到磁盘上,而是只帮我们在这里直接 echo,然后写入管道文件当中,但是管道文件当前是内存级的,所以你的大小没有变

    17810

    C语言第四章(进程间的通信,管道通信,pipe()函数)

    在父进程和子进程之间,父进程调用 fork() 函数创建了一个子进程。该程序基于尽可能少的关系来实现进程间通信。 父进程关闭管道的写入端口,只保留读取端,以便从子进程中读取数据。...子进程关闭管道的读取端口,只保留写入端口,让该进程可以向管道中写入数据。 在子进程内部,它打印了一条消息 “这里是子进程…” 然后使用 write() 函数将 “Hello, world!”...然后通过 fork() 函数创建一个子进程。在父进程中,通过 write() 方法向管道里面的写入端发送数据;而在子进程中,则通过 read() 从管道里面的读取端获取数据。...可以看到,父进程向子进程发送了一条消息 “Hello, child process!\n”,而子进程通过管道接收到该消息并输出。这表明,使用 pipe() 函数实现的进程间通信是有效的。...在父进程中,先调用 write() 方法将消息发送到管道写入端,发送完成后再关闭相应的文件描述符。而在子进程中,则先关闭写入端,接着通过 read() 方法从管道读取数据,并输出这条信息。

    9410

    进程间的通信--管道

    ID信息的消息字符串,用于子进程向父进程发送消息。...(rfd) 中读取消息并输出到控制台 子进程关闭不需要的管道读取端 (pipefd[0]),调用 subProcessWrite() 发送消息,然后关闭写入端 (pipefd[1])。...父进程关闭不需要的管道写入端 (pipefd[1]),调用 fatherProcessRead() 接收消息,然后关闭读取端 (pipefd[0])。...2.1.3管道的4种情况 如果管道是空的,并且写端文件描述符没有关闭,读取条件不具备,读进程(父进程)会被阻塞,自动等待读取条件具备(写入进程再重新写入)。...直接关闭,写端fd一直进行写入,这个管道称之为坏的管道,操作系统会杀掉对应的进程,属于异常情况,操作系统会给目标发送信号(13号:SIGPIPE)。

    7610

    linux网络编程系列(八)--优雅关闭以及如何检测对端已经关闭

    什么是优雅关闭 一种情况是在多进程并发时,假设客户端有两个进程,父进程和子进程,子进程是在父进程和服务器建立连接之后fork出来的,我们期望实现这样的功能: 子进程将数据写入套接字后close,并退出,...服务端接收完数据,直到检测到EOF,也关闭连接,并退出,接着父进程读取完服务端响应的数据,也退出,但如果子进程使用close的话,并不会发生4次挥手的过程,只是引用计数减1,服务端是接收不到EOF的,这时就需要使用优雅关闭了...还有一种情况,是说保持连接的某一端想关闭连接了,但它需要确保要发送的数据全部发送完毕以后才调用close,此种情况下也需要使用优雅关闭; 下面我们就来看看怎么优雅的关闭一个socket。 2....: shutdown(s, SHUT_WR); //就是说不会再有人往s上写数据了,那么服务端读取时自然就会读到EOF 2.1.3 shutdown和close区别 close函数会关闭套接字,如果有其他进程共享...,那么这个套接字仍然是打开的,可以读写,并不会发生四次挥手; shutdown则会根据how选项切断进程共享的套接字的该功能,比如所有试图读的进程都会接收到EOF标识,所有试图写的进程将会检测到SIGPIPE

    3K50

    【Linux】进程间通信——命名管道

    例如,使用echo命令向命名管道写入文本: echo "Hello, FIFO!"...> /path/to/your/fifo 需要注意的是,如果此时没有其他进程正在读取该命名管道,则上述命令将会阻塞,直到有读者出现。 从命名管道读取数据 另一个进程可以从命名管道中读取数据。...这通常也是通过标准输入输出重定向完成的: cat < /path/to/your/fifo 同样地,如果此时没有进程向命名管道写入数据,那么执行读操作的命令也会处于等待状态。...命名管道非常适合用于那些需要跨多个会话或用户之间的简单IPC(进程间通信)的情况。对于更复杂的需求,可能需要考虑其他的IPC机制如消息队列、共享内存等。 3....Server可执行程序: 读端也就是Server端关闭后,写端的进程会收到信号进而终止程序。

    13810

    【Linux】IPC 进程间通信(一):管道(匿名管道&命名管道)

    父进程向被打开文件的内核级缓冲区写入,子进程从被打开文件的内核级缓冲区读取,这样就实现了进程通信!...父进程向以写方式打开的文件的管道文件写入,子进程再从以读方式打开的文件的管道文件读取,从而实现管道通信。如果是要子进程向父进程传输数据,同理即可。...运行如下: 当我们到 65536 个字节时,管道已满,父进程读取了管道数据,子进程会继续进行写入,然后进行继续读取,就有点数据溢出的感觉 情况三:管道写端关闭 && 读端继续(读端读到0,表示读到文件结尾...,读端读完管道内部数据,再读取就会读取到返回值 0,表示对端关闭,也表示读到文件结尾 情况四:管道写端正常 && 读端关闭(OS 会直接杀掉写入进程) 情况二: 如何杀死呢?...管道的特点 管道是单向的:数据在一个方向上流动,从写端(写入数据的进程)到读端(读取数据的进程) 在写端,数据会被写入一个缓冲区,读端则从这个缓冲区读取数据 管道的缓冲区大小有限,因此如果写入的数据超过缓冲区容量

    13810

    pipe和pipefd

    管道允许两个进程之间进行单向数据传输,通常是一个进程向管道写入数据,而另一个进程从管道读取数据。...pipefd[1]:管道的写入端,通常用于向管道中写入数据。 在上述例子中,pipefd 被用作参数传递给 pipe 函数,并在子进程中用于读取数据,在父进程中用于写入数据。...,把父进程中休眠50秒 结果差不多64kb 写端退了,测试结果 结果是: 读端正常读,写端关闭,读端就会读到0,表明读到了文件(pipe)结尾,不会被阻塞 read读取成功会返回读到的字符个数,读到结尾返回...0开始读 想让父进程固定的向管道里写入指定大小字节的内容,必须读取四个字节,四个字节四个字节的写和读,这里的管道64kb 必须读取四个字节 如果父进程不给子进程发送数据呢?...再把任务装载进来 输出型参数用* 现在开始选择任务和进程 再把main中的任务弄成全局的 进行判断一下 测试 ,comcode和任创建的任务一致 这里的write是父进程进行写入,向子进程发送,子进程不得闲

    9310
    领券