管道大致分为两种:
1.匿名管道:这个一般只能用于父进程创建管道传递给子进程,可以父子进程通信
2.有名管道:这种管道存在于文件系统中,所以任意进程都能找到,都可以通过它来通信
API:
#include <unistd.h>
int pipe(int fds[2])
fds[0] 是读取文件描述符,也就是管道出口
fds[1] 是写文件描述符,也就是管道入口
创建一个匿名管道
成功返回0,失败返回-1
int dup(int oldfd);创建文件描述符的副本
int dup2(int oldfd,int target)让target 也指向该文件
/*************************************************************************
> File Name: pipe_simple.c
> Author: nealgavin
> Mail: nealgavin@126.com
> Created Time: Tue 03 Jun 2014 10:02:14 AM CST
************************************************************************/
#include<stdio.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <wait.h>
#define MAX_LINE 80
#define PIPE_STDIN 0
#define PIPE_STDOUT 1
int main()
{
const char*str = "A simple message !";
int ret,myPipe[2];
char buffer[ MAX_LINE+1 ];
//create pipe
ret = pipe( myPipe );
if (ret == 0)
{
if(fork() == 0)
{
puts("child first");
ret = read( myPipe[ PIPE_STDIN ],buffer,MAX_LINE );
buffer[ ret ] = 0;
printf( "child read %s\n",buffer );
}
else{
puts("father");
ret = write( myPipe[ PIPE_STDOUT ],str,strlen(str) );
ret = wait(NULL);
}
}
return 0;
}
/*************************************************************************
> File Name: pipe_execlp.c
> Author: nealgavin
> Mail: nealgavin@126.com
> Created Time: Tue 03 Jun 2014 10:52:18 AM CST
************************************************************************/
#include<stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main()
{
int pfds[2];
char ccc;
if( pipe(pfds) == 0 ) {
if(fork() == 0){
close(0);
dup2(pfds[1],1);
close(pfds[0]);
execlp("ls","ls","-a","-l",NULL);
}
else{
close(0);
dup2(pfds[0],0);
close(pfds[1]);
/*
while(ccc=getchar())
{
if(ccc == EOF)
break;
putchar(ccc);
}*/
execlp("wc","wc","-l",NULL);
}
}
return 0;
}
2.有名管道:
#include<sys/types.h>
#include<sys/stat.h>
int mkfifo(const char*pathname,mode_t mode)
要创建的管道文件名,权限
命名管道,除非有一个写入者已经打开命名管道,否则读取者不能打开命名管道。
/*************************************************************************
> File Name: pipe_mkfifo.c
> Author: nealgavin
> Mail: nealgavin@126.com
> Created Time: Tue 03 Jun 2014 11:16:14 AM CST
************************************************************************/
#include<stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <unistd.h>
int main()
{
int ret;
FILE* pfp=NULL;
const char*path = "pipe_data";
char s[1024];
ret = mkfifo(path,S_IFIFO | 0666);
printf("ret = %d\n",ret);
if( ret == 0 )
{
if(fork() == 0)
{
pfp = fopen(path,"w+");
puts("child fork datain");
while(~scanf("%s",s))
{
if(s[0] == '#')
break;
fprintf(pfp,"%s",s);
}
}
else
{
pfp = fopen(path,"r");
if(pfp != NULL)
{
fgets(s,1023,pfp);
printf("father:pipe out %s\n",s);
}
}
}
return 0;
}