《linux管道专题编程笔记docx》由会员分享,可在线阅读,更多相关《linux管道专题编程笔记docx(13页珍藏版)》请在金锄头文库上搜索。
1、linux管道linux管道基本概念1管道基本概念及操作管道基本概念q 管道是Unix中最古老的进程间通信的形式。q 我们把从一个进程连接到另一个进程的一个数据流称为一个“管道”比如:eg: ls | wc -l ps u wbm01|grep “aa”管道的本质=固定大小的内核缓冲区管道限制q 管道是半双工的,数据只能向一个方向流动;需要双方通信时,需要建立起两个管道q 只能用于具有共同祖先的进程(具有亲缘关系的进程)之间进行通信;通常,一个管道由一个进程创建,然后该进程调用fork,此后父、子进程之间就可应用该管道。匿名管道pipeq 包含头文件q 功能:创建一无名管道q 原型q int
2、pipe(int fd2);q 参数q fd:文件描述符数组,其中fd0表示读端, fd1表示写端q 返回值:成功返回0,失败返回错误代码管道创建后示意图管道基本编程示例2管道和文件描述符在一起管道命令的编程实现: ls | wc w文件描述符的深入理解#include #include #include #include #include #include #include #include #include #include #define ERR_EXIT(m) do perror(m); exit(EXIT_FAILURE); while(0)int main21(void )int
3、pipefd2;pid_t pid;if (pipe(pipefd) = -1 )printf(pipe() err.n);return -1;pid = fork();if (pid = -1)printf(fork err.n);return -1;if (pid = 0)close(pipefd0);/复制文件描述符pipefd1,给标准输出,言外之意:execlp的ls命令输出到管道中dup2(pipefd1, STDOUT_FILENO);close(pipefd1);execlp(ls, ls, NULL);/如果替换新的进程印象失败,则会执行下面一句话sprintf(stderr
4、, execute the cmd ls err.n);exit(0); else if (pid 0 )int len = 0; char buf100 = 0;close(pipefd1);/复制文件描述符pipefd0,给标准输入,言外之意:execlp的wc命令从管道中读dup2(pipefd0, STDIN_FILENO);close(pipefd0);/len = read(pipefd0, buf, 100);execlp(wc, wc, -w, NULL);printf(len:%d, buf:%s n, len , buf);/close(pipefd0);wait(NULL
5、);printf(parent .quitn);return 0;int main(int argc, char *argv)close(0); /关闭表示输入open(makefile, O_RDONLY); /makefile文件变成标准输入close(1);/关闭标准输出open(makefile2, O_WRONLY | O_CREAT | O_TRUNC, 0644); /maifle2变成标准输出execlp(cat, cat, NULL); /替换进程印象后,执行cat命令/cat命名从标准输入中按行读,紧接着写到标准输出return 0;2管道的读写规则管道读写规则研究(重点)
6、q 当没有数据可读时q O_NONBLOCK disable:read调用阻塞,即进程暂停执行,一直等到有数据来到为止。q O_NONBLOCK enable:read调用返回-1,errno值为EAGAIN。q 当管道满的时候q O_NONBLOCK disable: write调用阻塞,直到有进程读走数据q O_NONBLOCK enable:调用返回-1,errno值为EAGAINq 当管道不停的被写,写满的时候q O_NONBLOCK disable: write调用阻塞q O_NONBLOCK enable:调用返回-1,errno值为EAGAINq 如果所有管道写端对应的文件描述符
7、被关闭,则read返回0q 如果所有管道读端对应的文件描述符被关闭,则write操作会产生信号SIGPIPEq 当要写入的数据量不大于PIPE_BUF时,linux将保证写入的原子性。q 当要写入的数据量大于PIPE_BUF时,linux将不再保证写入的原子性。测试管道读(阻塞、非阻塞)测试管道两端读、写均关闭测试管道容量编程实践man fctl File descriptor flags The following commands manipulate the flags associated with a file descriptor. Currently, only one such
8、 flag is defined: FD_CLOEXEC, the close-on-exec flag. If the FD_CLOEXEC bit is 0, the file descriptor will remain open across an execve(2), otherwise it will be closed. F_GETFD Read the file descriptor flags. F_SETFD Set the file descriptor flags to the value specified by arg. File status flags Each
9、 open file description has certain associated status flags, initialized by open(2) and possibly modified by fcntl(2). Duplicated file descriptors (made with dup(), fcntl(F_DUPFD), fork(), etc.) refer to the same open file description, and thus share the same file status flags. The file status flags
10、and their semantics are described in open(2). F_GETFL Read the file status flags. F_SETFL Set the file status flags to the value specified by arg. File access mode (O_RDONLY, O_WRONLY, O_RDWR) and file creation flags (i.e., O_CREAT, O_EXCL, O_NOCTTY, O_TRUNC) in arg are ignored. On Linux this comman
11、d can only change the O_APPEND, O_ASYNC, O_DIRECT, O_NOATIME, and O_NONBLOCK flags.容量查询man -6 pipe Pipe Capacity A pipe has a limited capacity. If the pipe is full, then a write(2) will block or fail, depending on whether the O_NONBLOCK flag is set (see below). Different implementations have differe
12、nt limits for the pipe capacity. Applications should not rely on a particular capacity: an application should be designed so that a reading process consumes data as soon as it is available, so that a writing process does not remain blocked. In Linux versions before 2.6.11, the capacity of a pipe was
13、 the same as the system page size (e.g., 4096 bytes on x86). Since Linux 2.6.11, the pipe capacity is 65536 bytes.读写规则man -6 pipe If all file descriptors referring to the write end of a pipe have been closed, then an attempt to read(2) from the pipe will see end-of-file (read(2) will return 0). If all file descriptors referring to the read end of a pipe have been closed, then a write(2) will cause a SIGPIPE signal to be generated for the calling p