在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.csdn.net/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);
}
}