首页 > 代码库 > 管道通信

管道通信

管道大致分为两种:

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;
}