linux环境下进程间通信:管道和著名管道
在这个系列中,作者概述了Linux进程间通信的几种主要手段之间的管道和命名管道是最早的进程间通信机制。管道可以用于亲属进程之间的通信。一个著名的管道克服了管道名称的局限性,具有管道功能。
管道和名牌管道
在这个系列中,作者概述了Linux进程间通信的几种主要手段之间的管道是最著名的一个早期的进程间通信机制,可用于进程间的通信关系管道,有名管道克服了管道没有名字,因此,除了管道具有通信的功能,它还允许进程之间没有任何关系。承认写作规则的管道和管道是著名的阅读应用程序中的关键,本文详细论述了基本的通信机制管道和命名管道在写程序来验证其阅读说明规则,这样有利于提高读者对读写规则的认识,并提供应用实例。
1,管道概述和相关API应用
管道相关的1.1个关键概念
管道是Linux支持的原始UNIX IPC形式之一,具有以下特性:
管道是半双工的,数据只能朝一个方向流动,当双方需要沟通时,需要设置两个管道。
它只能在父子关系或兄弟关系过程中使用(亲属关系的过程);
单独的管道文件系统:管道两端的进程,是一个文件,但它不是一个普通的文件,它不属于一个文件系统,而是独立存在,构成一个单独的文件系统,并且只存在于内存中。
数据的读出和写入:由管道中的进程读出的内容由管道的另一端读出,每次写入管道缓冲区的内容,每次从缓冲器的头部读取数据。
创建1.2个管道:
#包括INT管(int fd { 2 })
这个函数创建在一个过程中管道的两端,没有太大的意义,在实际应用中,因此,在工艺管道()来创建管道,然后一般的叉子过程,然后通过管道实现之间的通信过程(所以它并不难推出来的,只要在亲缘关系、遗传关系存在两个过程,这里指的是一个共同的祖先,可以用管道来沟通)。
1.3管的读写规律:
管的端部可以用描述FD 0 }和FD { 1 }分开描述。需要注意的是,管道的两端固定重要,一端只能用于阅读,它是由描述字FD { 0 }来表示,称为读端的管道,而另一端只能用于写作,它是由描述字FD { 1 }来表示,它称为管道写端。如果你试图读取数据从管子的一端或写入管道读端,它将导致错误发生。我/一般文件输出功能可用于管道、关闭等,读,写,等等。
从管道读取数据:
如果管道的末端不存在,它被认为已经读取了数据的结束,而读函数返回了读出字节的0。
当写端管,如果字节数要求超过pipe_buf,它返回在现有管道的数据字节数,如果请求的字节数不大于pipe_buf,它返回的数据管道的字节数(在这一点上,管道的数据量小于请求的数据量);或者返回请求的字节数(此时,在请求管道的数据量不小于数据量)。注:(pipe_buf定义包括 / Linux /限制。h,不同的内核版本可能不同。POSIX。1要求pipe_buf是至少有512个字节,和Red Hat 7.2是4096)。
管道阅读规则的验证:
/ ************** * readtest。C * ************** / #包括#包括
将数据写入管道:
当数据被写入到管道,Linux将无法保证写入的原子性。管道缓冲区有一个空闲区域,写过程将尝试向管道写入数据。如果读取过程不读取管道缓冲区中的数据,则写操作将始终被阻塞。
注:这是写数据到管只有在管道的读端存在有意义。否则,向管道写入数据的进程将收到来自内核的sifpipe信号。应用程序可以处理信号或忽略信号(默认操作是应用程序的终止)。
流水线1的编写规则的验证:读端上写端的依赖性
#包括#包括主(){ int pipe_fd { 2 };pid_t
输出结果是破裂的管道,由于管道的结束和它的所有叉()产品已关闭。如果你保持阅读结束父进程,那么你可以在写管关闭父进程读取结束,它也将给管正常,所以读者可以通过本人验证。因此,当数据写入到管道,至少要有一个过程,在管道的读端不是封闭的,否则,就会出现上述错误。(管道坏了,sigpipe过程接收信号,并默认动作是终止进程)。
写作的2的管道规则验证:Linux不保证原子性验证写管道
#包括#包括#包括主(int argc)
结论:
写入次数小于4096时,写入是非原子的!
如果父进程中的两个写入字节的数目被更改为5000个,那么很容易得出以下结论:
当写入管道的数据量大于4096字节时,缓冲区的空闲空间将写入数据。在所有数据写入之前,如果没有进程读取数据,则不会阻塞任何进程。
管道应用的1.4个例子:
示例1:用于shell
管可用于输入和输出重定向,将一个命令直接到另一个命令的输入输出,例如,当一个shell程序(Bourne shell或C壳)型谁/ WC L,壳谁和WC管道程序将创建两个进程和两个进程。考虑下面的命令行:
杀死- l看到结果。
杀了我sigrtmin |美元grep操作结果如下:
30)电源故障信号31)32)33)sigsys sigrtmin sigrtmin + 134)+ 2,35)sigrtmin sigrtmin
例二:亲情的进程间通信
下面的例子给出了管道的具体应用。父进程通过管道发送一些命令到子进程,子进程解析命令,并根据命令进行处理。
#包括#包括主(){ int pipe_fd { 2 };pid_t
1.5管的局限性
管道的主要局限性反映在管道的特性上:
只支持单向数据流;
它只能在进程与亲属关系之间使用。
没有名字;
管道的缓冲区是有限的(管道系统存在于内存中,当管道被创建时,页面的大小被分配给缓冲区)。
管道传输格式自由字节流,这要求读者和管道的读者必须预先商定数据的格式,例如有多少字节被计算为一个消息(或命令或记录)。
2,著名管道概述及相关API应用
与著名管道有关的2.1个关键概念
管道应用的一个主要的限制是,它没有名字,所以它只能用于与亲戚的进程间通信。在该命名管道或FIFO,限制被克服。差异的FIFO和管之间,它提供了一个路径名与它存在于文件系统在一个FIFO文件的形式。所以,即使有先进先出的创作不存在相关的过程,只要你可以访问路径,可以相互沟通,通过FIFO(访问过程和FIFO,创作之间的路径,因此,不能通过过程)FIFO的过程也可以交换数据。值得注意的是,FIFO严格遵循先进先出,它总是返回的数据从开始到管道和FIFO,写他们的末尾添加数据。他们不支持文件位置的操作如我寻找()。
2.2创建一条著名的管道
#包括#包括int mkfifo(const char*的路径名,mode_t模式)
这个函数的第一个参数是一个常见的路径名称,创建后的FIFO的名字,第二个参数是在开放模式参数相同()函数打开普通文件。如果mkfifo的第一个参数是一个已经存在的路径名,它将返回eexist误差。因此,典型的调用代码首先检查是否返回错误。如果我们返回错误,那么我们只调用打开FIFO的函数,一般文件的I/O函数可以用于FIFO,例如关闭、读、写等。
2.3条著名管道的开放规则
一条有名的管道比一根管子的开启操作更开放。
先进先出的开放规则:
如果当前的操作是打开阅读和打开FIFO,如果已经有一个相应的过程写作,打开FIFO,那么当前打开操作将返回成功;否则,可能会被阻塞直到相应的过程写打开FIFO(当前打开操作设置;阻断标记)或回(目前开放的操作没有设置阻塞的标志)。
如果手术是目前公开写打开FIFO,如果已经有一个相应的过程和打开FIFO,当前打开的操作将返回成功;否则,可能会被阻塞直到相应的过程和打开FIFO(当前打开操作设置阻塞标记);或者,返回enxio误差(目前开放的操作没有设置阻塞的标志)。
有关开放规则的核查,见附件2。
著名管道读写2.4定律
从FIFO读取数据:
常规:如果一个进程阻塞FIFO,以便从FIFO读取数据,则称为进程中的读操作,它是一个设置阻塞标志的读操作。
如果有一个进程打开FIFO写,还有在当前FIFO没有数据,它将阻止所有的读操作,设置挡标志的时间。没有阻塞读操作的旗帜,返回- 1,和当前errno值EAGAIN,提醒再次尝试。
对于阻塞操作,阻塞原因有两个:目前FIFO中有数据,但还有其他读取这些数据的过程。换句话说,FIFO中没有数据,阻塞的原因是FIFO中有新的数据写入,不管写入的数据量是多少,以及读操作请求的数据量。
阻断这个标语只开放到第一次读操作的过程,如果这个过程中有一个在第一个读操作多个读操作顺序是引起和读操作后,读操作将其他的实施将不再阻止,甚至在一个读操作,而不是在FIFO数据(在这个时候,读操作返回0)。
如果没有进程写入打开FIFO,则设置阻塞标志的读操作将被阻止。
注意:如果FIFO中有数据,则阻塞符号的读操作不会被阻塞,因为FIFO中的字节数小于读取的请求数。此时,读操作返回FIFO中的数据量。
将数据写入FIFO:
惯例:如果一个进程阻塞了FIFO,以便将数据写入FIFO,那么这个过程中的写操作称为阻塞标志的写操作。
对于阻塞标志的写操作:
当要写入的数据量不超过pipe_buf,Linux将保证写入的原子性。如果管道空闲缓冲区不足以容纳的字节数写的,它会去睡到写缓冲区中的字节数可以容纳。
当要写入的数据量大于pipe_buf,Linux将不再保证写入的原子性。当FIFO缓冲区有一个自由区,写的过程中会向管道写入数据,和写操作返回后写的所有数据请求的书面。
无阻塞标志的写操作:
当要写入的数据量大于pipe_buf,Linux将不再保证写入的原子性。写完所有的FIFO缓冲区的写操作返回自由。
当要写入的数据量不超过pipe_buf,Linux将保证写入的原子性。如果当前FIFO缓冲区可以容纳自由的请求写的字节数,它将写作后成功返回。如果当前FIFO缓冲区不能包含写入的字节数,将返回EAGAIN错误的,它将改写后。
先进先出读写规则的验证:
这里有两个FIFO的读写程序,它可以通过调整程序中的几个程序或程序的命令行参数来验证各种FIFO读写规则。
程序1:写FIFO的程序
# # # #包括包括包括包括
程序的应用说明:
将读程序编译成两个不同的版本:
块读版本:BR
NBR的无阻塞读版
将编写程序编译成24个版本:
非阻塞和请求写的字节数大于pipe_buf版本:nbwg
非阻塞和请求写的字节数不大于pipe_buf版本:版本NBW
字节封锁并请求数大于pipe_buf版本:BWG
字节封锁和请求次数不大于pipe_buf版本:版本BW
BR、NBR和w将代替阻塞读取,在相应程序中无阻塞读取。
验证阻塞写操作:
非原子性时,写入的数据量大于pipe_buf:
丁腈橡胶1000
BWG
所请求的数据在数据量不大于pipe_buf原子性:
丁腈橡胶1000
BW
验证非阻塞写操作:
非原子性时,写入的数据量大于pipe_buf:
丁腈橡胶1000
nbwg
需要写入的数据量不超过pipe_buf原子性。
丁腈橡胶1000
NBW
无论写打开阻塞设置标志或写在请求的字节数大于4096时,它不保证写入的原子性。但这两者之间有本质的区别。
对于阻塞写入,写入操作总是在写入FIFO的空闲区域之后等待,直到写入所有数据,写入请求的数据最终将写入FIFO。
非阻塞写返回(实际写入的字节数)写满FIFO的空闲区域之后,所以一些数据不能在结尾写入。
读取操作的验证更简单,不再讨论。
2.5大管道应用实例
当验证了相应的读写规则时,应用程序实例似乎是不必要的。
总结:
用在两个方面:(1)管道中常用的管道(如shell重定向输入),在这种方式下,管道的创建对用户是透明的;(2)用于进程间通信的系统发育关系,用户创建他们自己的管道,并完成读写操作。
FIFO可以说是管道的推广,它克服了管道无名的局限性,使得不相关的进程也可以采用先进先出的通信机制进行通信。
流水线和FIFO的数据是字节流,应用程序必须确定应用程序之间特定的传输协议,并使用消息传播特定的含义。
要灵活地应用管道和FIFO,了解它们的读写规则至关重要。
该操作的结果为:1:杀死l显示当前系统支持的所有信号:
1)2)3)SIGQUIT SIGHUP信号情报sigill5)4)6)sigabrt sigtrap
除了在这里描述管道应用程序之外,下一个主题还将讨论这些信号。
附件2:验证FIFO的打开规则(主要是验证打开与打开的依赖关系)