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

linux——管道详解

使用单个固定缓冲区也会带来问题,比如在写管道时可能变满,当这种情况发生时,随后对管道write()调用默认地被阻塞,等待某些数据被读取,以便腾出足够空间供write()调用写。...读取进程也可能工作得比写进程快。当所有当前进程数据已被读取时,管道变空。当这种情况发生时,一个随后read()调用默认地被阻塞,等待某些数据被写入,这解决了read()调用返回文件结束问题。...写入函数向内存写入数据之前,必须首先检查 VFS 索引节点中信息,同时满足如下条件时,才能进行实际内存复制工作: 内存中有足够空间可容纳所有要写入数据 内存没有被读程序锁定 如果同时满足上述条件...否则,写入进程就休眠 VFS 索 引节点等待队列,接下来,内核调用调度程序,而调度程序会选择其他进程运行。...专门为每个管道使用内核级缓冲区确切为 4096 字节。 除非阅读器清空管道,否则一次超过 4K 写操作将被阻塞。 实际上这算不上什么限制,因为读和写操作是不同线程实现

2.9K20

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

默认情况下,读取方将会阻塞,直到从通道能够读取到字节数据,而写入写完它字节数据后,发送流已终止(end-of-stream)标志。...: close(pipeFDs[ReadEnd]); /* called in parent code */ 然后父进程向无名管道写入某些字节数据(ASCII 代码),子进程读取这些数据,然后向标准输出回放它们...例如,假如进程 P1 向管道写入内容: foo bar 同时进程 P2 并发地写入: baz baz 到相同管道,最后结果似乎管道内容将会是任意错乱,例如像这样: baz foo baz bar...: % mkfifo tester ## 创建一个备份文件,名为 tester % cat tester ## 管道内容输出到 stdout 最开始,没有任何东西会出现在终端,因为到现在为止没有命名管道写入任何东西...有一个名为 mkfifo 库函数,用它可以程序创建一个命名管道,它将在下一个示例中被用到,该示例由两个进程组成:一个向命名管道写入,而另一个从该管道读取

1.2K20
您找到你想要的搜索结果了吗?
是的
没有找到

【翻译】XV6-DRAFT as of September 3,2014 第0章 操作系统接口

当一个进程不再执行而让出CPU时,Xv6保存了该进程CPU上某些相关寄存器内容,方便该进程在下次占用CPU时恢复到上次运行状态并接着运行。...父进程程序fork函数返回是子进程pid,而在子进程程序fork函数返回0。...现在你应该很清楚为什么把fork与exec分开调用是个好主意了:这种分离使得shell可以子进程执行指定程序之前对子进程进行修改。...如果管道没有可用数据,从管道读取数据系统调用read一直等待,直到有数据写入管道或者所有与管道写端口关联文件描述符都被关闭。...在后面这种情况,read返回0,就好像数据读取已经到了文件结束部分(end-of-file)。读操作会一直阻塞直到不可能有新数据到来,这就是为什么我们执行wc之前要关闭子进程写端口。

58260

MIT 6.S081 (BOOK-RISCV-REV1)教材第一章内容 --- 操作系统接口

尽管最初子进程与父进程有着相同内存内容,但是二者在运行拥有不同内存空间和寄存器: 一个进程改变变量不会影响到另一个进程。...---- 管道 管道是作为一对文件描述符公开给进程小型内核缓冲区,一个用于读取,一个用于写入数据写入管道一端使得这些数据可以从管道另一端读取管道为进程提供了一种通信方式。...事实上,read新数据不可能到达前会一直阻塞,这是子进程执行上面的wc之前关闭管道写入端非常重要一个原因: 如果wc文件描述符之一指向管道写入端,wc永远看不到文件结束。...然后,例如: echo hi | wc将不会产生输出,因为当echo hiruncmd退出时,内部进程退出,而不会调用fork来运行管道右端。...第三,管道允许并行执行管道阶段,而文件方法要求第一个程序第二个程序启动之前完成。 第四,如果实现进程间通讯,管道块读写比文件非块语义更有效率。

21120

【操作系统】进程间通信——管道

具体操作流程: p1 创建管道。 创建子进程。 子进程中使用execl()函数,子进程替换为程序p2。(使用execl函数时,把管道读端作为参数。)...父进程,通过管道给子进程发送字符串。 p2 从参数获取管道读端(参数即p2main函数参数)。 读管道读取字符串打印出来。...在读取数据时,管道读端数据会越读越少,而在写入数据时,写入数据会累加,添加到尾部。...如果有多个进程,每个进程写端都关闭了,read()也将不会阻塞。 小提示: 为了避免不必要麻烦,例如没有可读数据时read函数阻塞,我们可以没用管道端口关闭。.../pclose popen作用:用于两个进程之间传递数据:程序A中使用popen调用程序B时,有两种用法: 程序A读取程序B输出(使用fread读取); 程序A发送数据给程序B,以作为程序B

52320

浅谈网络编程

通过管道通信大概思路是,首先创建一个管道,然后子进程向管道写入信息,父进程从管道读取信息,这样就可以做到父子进程直接实现通信了: <?...PHP_EOL; 时,运行程序:   能看到程序立马输出 空串,并等待 1秒 之后退出。这是因为。当读取是非阻塞情况下,父进程进行读取信息时候,不会等待立马有信息,管道没有信息,也会立马返回。...阻塞与非阻塞 阻塞和非阻塞关注程序等待调用结果(消息,返回值)时状态. 阻塞调用是指调用结果返回之前,当前线程会被挂起。调用线程只有得到结果之后才会返回。...非阻塞调用指在不能立刻得到结果之前,该调用不会阻塞当前线程。...显著减少程序大量并发连接只有少量活跃情况下CPU利用率,他不会复用文件描述符集合来传递结果,而迫使开发者每次等待事件之前都必须重新设置要等待文件描述符集合,另外就是获取事件时无需遍历整个文件描述符集合

86520

浅谈网络编程

通过管道通信大概思路是,首先创建一个管道,然后子进程向管道写入信息,父进程从管道读取信息,这样就可以做到父子进程直接实现通信了: <?...PHP_EOL; 时,运行程序:   能看到程序立马输出 空串,并等待 1秒 之后退出。这是因为。当读取是非阻塞情况下,父进程进行读取信息时候,不会等待立马有信息,管道没有信息,也会立马返回。...阻塞与非阻塞 阻塞和非阻塞关注程序等待调用结果(消息,返回值)时状态. 阻塞调用是指调用结果返回之前,当前线程会被挂起。调用线程只有得到结果之后才会返回。...非阻塞调用指在不能立刻得到结果之前,该调用不会阻塞当前线程。...显著减少程序大量并发连接只有少量活跃情况下CPU利用率,他不会复用文件描述符集合来传递结果,而迫使开发者每次等待事件之前都必须重新设置要等待文件描述符集合,另外就是获取事件时无需遍历整个文件描述符集合

58300

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

匿名管道这里,我们通过fork创建子进程,让子进程继承父进程文件描述符表,这样子进程中会有一个指向匿名管道文件文件描述符,并且父进程也会有这样文件描述符,当然是fork之前,父进程要打开一个管道文件...进程等待管道文件,此时PCB会被放在管道文件等待队列,当管道重新出现数据时,PCB会被重新投入到运行队列数据从内核拷贝到用户层,只要没有数据,该进程就会一直阻塞等待 如果一直不写入,则父进程一直阻塞等待...服务端在读取时候,读取内容进行字符串化处理,所以我们读取字节数s对应下标的位置字符改为\0,这样就成功对管道读取数据进行字符串化处理了。...第二个细节:键盘输入时多输入了\n回车,这样写入管道数据末尾会多一个\n字符,server读取进行打印时候,如果多输出了endl,则输出到显示器上结果会多一个空行,所以写入时候,我们可以...共享内存缺点:不进行同步与互斥操作,没有对数据做任何保护! 如果读端读完写端写某条消息后,此时若管道无新写入数据,则读端自动会阻塞在那里,不会继续读取已经被读取数据 4.

1.3K40

Linux进程间通信——匿名管道

写入内容每次都添加到管道缓冲区末尾,并且每次都是从缓冲区头部读取数据。 Linux建立无名管道函数是pipe函数。它需要头文件是#include....为了避免不必要一些错误,使用管道文件要先创建管道文件,然后创建新进程,这样所有的进程才能共享这个管道文件。...代码为了避免向读取写入和从写入读取而引发错误,在读时候关闭写端,时候关闭读端。 代码先让父进程向管道文件写入了字符串“Hello World!”。...然后子进程读取管道文件字符串,并向屏幕打印。程序执行结果如下: ? 如果子进程读取管道文件为空,那么read()函数将会使得进程阻塞,这时候父进程将会执行,然后完成对管道文件写入。...之后wait()父进程挂起,子进程完成读取。同样,管道已经满时,进程再试图写管道,在其它进程从管道移走数据之前,写进程一直阻塞

1.4K10

Linux 进程间通信之管道(pipe)、命名管道(FIFO)与信号(Signal)

写入函数向内存写入数据之前,必须首先检查 VFS 索引节点中信息,同时满足如下条件时,才能进行实际内存复制工作: ·内存中有足够空间可容纳所有要写入数据; ·内存没有被读程序锁定...如果同时满足上述条件,写入函数首先锁定内存,然后从写进程地址空间中复制数据到内存。 否则,写入进程就休眠 VFS 索引节点等待队列,接下来,内核调用调度程序,而调度程序会选择其他进程运行。...当数据写入内存之后,内存被解锁,而所有休眠索引节点读取进程会被唤醒。 管道读取过程和写入过程类似。...FIFO读写规则 1.从FIFO读取数据:约定:如果一个进程为了从FIFO读取数据而阻塞打开了FIFO,那么称该进程内读操作为设置了阻塞标志读操作 2.从FIFO写入数据:约定:如果一个进程为了向...第一,一些系统,当一个进程处理完中断信号返回用户态之前,内核清除用户区设定对该信号处理例程地址, 即下一次进程对该信号处理方法又改为默认值,除非在下一次信号到来之前再次使用signal系统调用

2.3K30

进程间通信和线程间通信区别_有些线程包含多个进程

例子:主程序阻塞了cltr+csigint信号。用sigpromasksigint假如阻塞信号集合。 管道管道允许进程之间按先进先出方式传送数据,是进程间通信一种常见方式。...管道实质是一个内核缓冲区,进程以先进先出方式从缓冲区存取数据:管道一端进程顺序地进程数据写入缓冲区,另一端进程则顺序地读取数据,该缓冲区可以看做一个循环队列,读和写位置都是自动增加,一个数据只能被读一次...,用pclose关闭读管道; 接着用popen函数创建一个写管道,调用fprintf函数buf内容写入管道,运行grep命令。...一个进程写入共享内存信息,可以被其他使用这个共享内存进程,通过一个简单内存读取错做读出,从而实现了进程间通信。...例子:设计两个程序,通过unix system v共享内存机制,一个程序写入共享区域,另一个程序读取共享区域。

85630

进程间通信

用例:从键盘读取数据,写入管道读取管道,写到屏幕 #include #include #include #include <unistd.h...,则read返回0 如果所有管道读端对应文件描述符被关闭,则write操作会产生信号SIGPIPE,进而可能导致write进程退出 当要写入数据量不大于PIPE_BUF时,linux保证写入原子性...命名管道是一种特殊类型文件 创建一个命名管道 命名管道可以从命令行上创建,命令行方法是使用下面这个命令: $ mkfifo filename 命名管道也可以从程序里创建,相关函数有: int mkfifo...,因此各进程间竞争使用这些资源,进程这种 关系为进程互斥 系统某些资源一次只允许一个进程使用,称这样资源为临界资源或互斥资源。...进程涉及到互斥资源程序段叫临界区 特性方面 IPC资源必须删除,否则不会自动清除,除非重启,所以system V IPC资源生命周期随内核

99520

Linux进程间通信【匿名管道

,拿数据按报文段拿 不论写端写入了多少数据,只要写端停止写入,读端都可以数据读取 5.具有一定协同能力,让 读端 和 写端 能够按照一定步骤进行通信(自带同步机制) 当读端进行从管道读取数据时,...cnt++ << " 字节数据" << endl; } 结果:一段时间后,管道被写满,写端无法写入数据,进入阻塞状态 只有当读端尝试管道数据读走一部分后,写端才能继续写入 形象化理解...管道为空:垃圾桶为空时,你不会去倒垃圾(读端阻塞),因为没有垃圾,需要等有垃圾了(写入数据)才去倒 管道为满:垃圾桶垃圾装满时,无法再继续扔垃圾(写端阻塞),需要等把垃圾倒了(读取数据),才能继续扔垃圾...因为管道是单流向通信,写端都关闭了,证明不会再有数据写入,因此当读端把剩余数据都读取后,每次都是读取 0 字节数据,表明此时已经读到了结尾,读端也可以结束读取了 6.4、场景四 通信过程,关闭读端,...,本文中,我们首先学习了什么是 IPC,以及 IPC 发展历史及分类;然后从 管道 匿名管道 入手,介绍了 管道 各种特性、场景及 匿名管道 使用;最后通过一个简单 匿名管道 进程控制程序

22420

Linux通过匿名管道进行进程间通信

一、什么是管道 如果你使用过Linux命令,那么对于管道这个名词你一定不会感觉到陌生,因为我们通常通过符号“|”来使用管道,但是管理真正定义是什么呢?...,即通过stdio函数(如fwrite)向被调用程序写数据,而被调用程序就可以自己标准输入读取这些数据。...所以启动程序(command命令程序之前先启动shell来分析命令字符串,也就可以使各种shell扩展(如通配符)程序启动之前就全部完成,这样我们就可以通过popen启动非常复杂shell命令...例子: 首先,我们原先进程创建一个管道,然后再调用fork创建一个新进程,最后通过管道两个进程之间传递数据。...父进程则相对简单,它首先关闭读管道,然后管道写入数据,再关闭写管道就完成了它任务。

1.3K21

FIFO:不是文件文件

,不必由fork产生也可以使用。...文件; 3) 如果进程以读写方式打开FIFO,此时open将不再阻塞,但是如果此时没有写进程向管道内写数据,则读取阻塞在read上,直到有进程写入数据为止。...(需要注意是如果之前有进程写入过数据,但是该进程本进程open之前已经关闭FIFO,则相应数据是读不到); 4) 如果进程以读写方式打开FIFO,此时open将不再阻塞,不管有没有读进程从管道读数据...6 /* No such device or address */); 一般很少用读写方式打开FIFO,因为那样很容易读到自己写入数据,除非此FIFO就是用来进程内部多个线程之间使用。...0; 对于第1点,特别声明一下,就是PIPE,多对一情况与一对一读写进程不同,当读进程退出时,多个写进程并没有收到SIGPIPE信号,详见下面这篇文章: 多进程管道读写一些疑问 总之,从各方来说

76630

linux系统编程之管道(二):管道读写规则和Pipe Capacity、PIPE_BUF

return 0; } 程序中将写端文件状态标志设置为非阻塞,当管道被写满时不会等待其他进程读取数据,而是直接返回-1并置errno,输出如下: simba@ubuntu:~/Documents...四、如果所有管道写端对应文件描述符被关闭(管道写端引用计数等于0),那么管道剩余数据都被读取后,再次read会返回0 示例程序如下: /*****************************...68k,即每个子进程完全写入68k才返回,而父进程对管道进行阻塞读取,每次读取4k,打印每4k最后一个字符,如果没有数据到达就阻塞等待,如果管道剩余数据不足4k,read 很可能返回 < 4k,但因为我们写入...需要注意是是边写边读,因为前面说过管道容量只有64k,当管道被写满时子进程就阻塞等待父进程读取后再写入。...读端也不能设置为非阻塞,如果此时尚未有数据写入管道为空)则返回-1并置错误码为EAGAIN,如果有部分数据已经写入,则读取数据字节数也是不确定,需要检查read返回值。

3.1K90

招式修炼-redis持久化和管道

1.1.快照流程 执行bgsave命令(此时redis会fork一个子进程,子进程负责生成硬盘文件,父进程负责继续接受命令) 或执行save命令(和bgsave命令不同,发送save命令后,到系统创建快照完成之前系统不会再接收新命令...,换句话说save命令会阻塞后面的命令,而bgsave不会) 用户配置文件了配置了类似这样命令: save 900 1 // 900内,有1条写入,则产生快照 save 300 1000...如果创建RDB文件时出现了错误,Redis不会将它用于替换原来文件,所以出错时不会影响到之前保存版本。...3.总结 Redis 默认开启RDB持久化方式,指定时间间隔内,执行指定次数写操作,则将内存数据写入到磁盘。 RDB 持久化适合大规模数据恢复但它数据一致性和完整性较差。...管道总结 打包redis管道可以多个命令打包,一次性发送给服务器端处理,当命令之间不存在依赖关系时,相比于一条命令一次请求普通操作方式,管道操作几乎是对使用者透明

50530

Linux 进程间通信:管道

用一个图来说明这个程序状态就是这样: image.png 一个进程自己给自己发送消息这当然不叫进程间通信,所以实际情况我们不会在单个进程中使用管道。...使用同一个管道父子进程可以分时给对方发送消息。我们也可以看到对管道读写一些特点,即: 管道没有数据情况下,对管道读操作会阻塞,直到管道内有数据为止。...当一次写数据量不超过管道容量时候,对管道写操作一般不会阻塞,直接将要写数据写入管道缓冲区即可。 当然写操作也不会再所有情况下都不阻塞。这里我们要先来了解一下管道内核实现。...而PIPESIZE影响是,大于其长度写操作会被阻塞,直到当前管道数据被读取为止。 Linux 2.6.11之前,PIPESIZE和PIPEBUF实际上是一样。...FIFO 命名管道底层实现跟匿名管道完全一致,区别只是命名管道会有一个全局可见文件名以供别人open打开使用。再程序创建一个命名管道文件方法有两种,一种是使用mkfifo函数。

8.3K21

PHP进程通信之管道与消息队列(二十三节)

/test.log", "a"), ); // 这个测试PHP程序工作目录,我设置为当前了 $s_cwd = './'; // 这个管道就是「PHP程序」与「bash程序」之间 // 这个管道是双向...就是说: // PHP程序向$a_pipes[0]内容,而bash从$a_pipes[0]内容 // PHP程序从$a_pipes[0]内容,而bash向$a_pipes[1]内容 //...()函数;除此之外,既然这种消息队列是系统维护,所以理论上只要外界程序知道这个消息队列ID或KEY,那么跨语言之间也可以通过这个消息队列进行通信,比如使用PHP向消息队列写入数据,使用Python...// 向消息队列写入消息 // 使用msg_send()向消息队列写入消息,具体可以参考文档内容 msg_send( $queue, 1, "helloword" );...//var_dump( msg_stat_queue( $queue ) ); // 向消息队列写入消息 // 使用msg_send()向消息队列写入消息,具体可以参考文档内容 msg_send(

1.4K31

扫码

添加站长 进交流群

领取专属 10元无门槛券

手把手带您无忧上云

扫码加入开发者社群

相关资讯

热门标签

活动推荐

    运营活动

    活动名称
    广告关闭
    领券