在linux系统中,管道是一种特殊的文件,它的主要作用是实现进程间的通信。
管道的一个显著特点是:当一个管道建立后,将获得两个文件描述符,分别用于对管道读取和写入,通常将其称为管道的写入端和读取端,从写入端写入管道的任何数据都可以从读取端读取。对于一个进程来说,管道的写入和读取操作与写入和读取一个普通文件没有区别,只是在内核中通过这种机制来实现进程间的通信。
管道的局限性:
1,管道只能用于两个进程间的通信,不能用与多个(>3)进程间的通信。
2,这两个进程要有同源性,即他们必须是最终由同一个进程所派生的进程。
3,管道是半双工方式的,即只允许单向传输数据。
创建pipe管道函数:
int pipe(int file_descriptor[2]);
函数pipe填充的两个整数的含义是两个文件描述符,任何向file_descriptor[1](写入端)写入的数据,可以从file_descriptor[0](读取端)中读取,并且写入的数据符合先入先出的规则.
例 pipe.c:
/* * ===================================================================================== * * Filename: pipe.c * * Description: * * Version: 1.0 * Created: 2012年03月11日 14时21分11秒 * Revision: none * Compiler: gcc * * Author: MaZheng (blog.youkuaiyun.com/mazheng1989), mazheng19891019@gmail.com * Company: Dalian University Of Technology * * ===================================================================================== */ #include<stdio.h> #include <unistd.h> #include <string.h> #include <sys/types.h> #include <stdlib.h> int main() { int data_processed; int file_pipes[2]; const char some_data[]="123"; char buffer[BUFSIZ+1]; int fork_result; memset(buffer,'\0',sizeof(buffer)); if(pipe(file_pipes)==0){ fork_result=fork(); /* 设置进程 */ if (fork_result==-1){ /* 判断设置进程是否出错 */ fprintf(stderr,"Fork failure"); exit(1); } /* 下面判断,若是是子进程则读管道数据,父进程则向管道写数据 */ if(fork_result==0){ /* 判断是否子进程 */ data_processed=read(file_pipes[0],buffer,BUFSIZ); /* 从管道读数据 */ close(file_pipes[1]); printf("Read %d bytes:%s\n",data_processed,buffer); exit(1); } else { /* 父进程 */ data_processed=write(file_pipes[1],some_data,strlen(some_data)); /* 向管道写数据 */ close(file_pipes[0]); printf("Wrote %d bytes\n",data_processed); } } exit(1); } 程序运行:./pipe
执行结果:
Wrote 3 bytes
Read 3 bytes:123
利用管道进行通信成功!
man pipe
里面的例子:
#include <sys/wait.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> int main(int argc, char *argv[]) { int pipefd[2]; pid_t cpid; char buf; if (argc != 2) { fprintf(stderr, "Usage: %s <string>\n", argv[0]); exit(EXIT_FAILURE); } if (pipe(pipefd) == -1) { perror("pipe"); exit(EXIT_FAILURE); } cpid = fork(); if (cpid == -1) { perror("fork"); exit(EXIT_FAILURE); } if (cpid == 0) { /* Child reads from pipe */ close(pipefd[1]); /* Close unused write end */ while (read(pipefd[0], &buf, 1) > 0) write(STDOUT_FILENO, &buf, 1); write(STDOUT_FILENO, "\n", 1); close(pipefd[0]); _exit(EXIT_SUCCESS); } else { /* Parent writes argv[1] to pipe */ close(pipefd[0]); /* Close unused read end */ write(pipefd[1], argv[1], strlen(argv[1])); close(pipefd[1]); /* Reader will see EOF */ wait(NULL); /* Wait for child */ exit(EXIT_SUCCESS); } }