c++小牛钱小白

c中linux中进程间通信IPC之匿名管道PIPE在实战中的应用??

案例1

//多进程中,子进程未执行??

#include <stdio.h>

#include <stdlib.h>

#include <errno.h>

#include <string.h>

#include <errno.h>


#define N 10

#define MAX 100


//子进程为什么没有执行??子进程未打印??只执行父进程??

int child_read_pipe(int fd)

{

char buf[N];

int n = 0;


//while(1){

n = read(fd, buf, sizeof(buf));

printf("Read %d bytes:%s\n", n, buf);

//if(strncmp(buf, "quit", 4) == 0)

//break;

//}

return 0;

}


int father_write_pipe(int fd)

{

char buf[MAX] = {0};


//while(1){

printf(">");

//fgets(buf, sizeof(buf), stdin);

sprintf(buf, "This is father process!\nquit\n");

buf[strlen(buf)-1] = '\0';


write(fd, buf, strlen(buf));

printf("Write bytes is:%s\n", buf);

usleep(500);

//if(strncmp(buf, "quit", 4) == 0)

//break;

//}

return 0;

}


//为什么子进程读的时候未执行,父进程写的时候执行了??

int main()

{

pid_t pid;// 也可以定义为int pid

    int n, m;

    int fd[2];

    char buf[1000 * 6] = {0}, rbuf[100] = {0};

pid = fork();

    if(pipe(fd) < 0)

    {

        perror("Fail to pipe!");

        exit(EXIT_FAILURE);

    }


    if(pid < 0)

    {

        perror("Fail to fork!");

        exit(EXIT_FAILURE);

    }else if(pid == 0){

printf("Read port begin.\n");

child_read_pipe(fd[0]);

printf("Read port begin.\n");

        /**

//sleep(5);

//为什么读出来的内容,是前10个字符,后面是全部内容??

//close(fd[1]);

m = read(fd[0], rbuf, sizeof(rbuf));

printf("Read %d bytes to pipe and size is:%s.\n", m, rbuf);

        */

sleep(3);

    }else{

printf("Write port begin.\n");

father_write_pipe(fd[1]);

printf("Write port close.\n");

/**

//close(fd[0]);

sprintf(buf, "This is parent process!");

        //while(1)

        //{

            n = write(fd[1], buf, sizeof(buf));

            printf("Write %d bytes to pipe and size is:%s.\n", n, buf);

        //}

*/

printf("Read end, errno is:%d\n", errno);

perror("Read result");

    }

//exit(EXIT_SUCCESS);

    //return 0;

}

案例2

//父进程读取文件的内容,写到无名管道,子进程从管道中读取内容写到另一个文件??

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <errno.h>

#include <sys/stat.h>

#include <sys/types.h>

#include <fcntl.h>


#define MAX 100


int child_work(int pfd,char *fname)

{

    int n,fd;

    char buf[MAX];


    if((fd = open(fname,O_WRONLY | O_CREAT | O_TRUNC,0666)) < 0)

    {

        fprintf(stderr,"Fail to open %s : %s.\n",fname,strerror(errno));

        return -1;

    }


    while( n = read(pfd,buf,sizeof(buf)) )

    {

        write(fd,buf,n);

    }

    

    close(pfd);


    return 0;

}


int father_work(int pfd,char *fname)

{

    int fd,n;

    char buf[MAX];


    if((fd = open(fname,O_RDONLY)) < 0)

    {

        fprintf(stderr,"Fail to open %s : %s.\n",fname,strerror(errno));

        return -1;

    }


    while(n = read(fd,buf,sizeof(buf)))

    {

        write(pfd,buf,n);

    }

    

    close(pfd);


    return 0;

}


//思考:父进程什么时候结束,子进程什么时候结束?

int main(int argc,char *argv[])

{

    int pid;

    int fd[2];

/** */

FILE * fp;

fp = fopen ("file.txt", "w+");

fprintf(fp, "%s %s %s %d", "We", "are", "in", 2014);

fclose(fp);

//初始化参数失败??

//argv[1] = "file.txt";

//argv[2] = "wfile.txt";

system("ls");

    if(argc < 3)

    {

        fprintf(stderr, "usage %s argv[1] argv[2].\n", argv[0]);

printf("2 usage %X argv[1] argv[2].\n", argv[0]);

perror("3 usage error");

        exit(EXIT_FAILURE);

    }


    if(pipe(fd) < 0)

    {

        perror("Fail to pipe");

        exit(EXIT_FAILURE);

    }


    if((pid = fork()) < 0)

    {

        perror("Fail to fork");

        exit(EXIT_FAILURE);

    

    }else if(pid == 0){

        

        close(fd[1]);

        child_work(fd[0],argv[2]);

    

    }else{

    

        close(fd[0]);

        father_work(fd[1],argv[1]);

        wait(NULL);

    }


    exit(EXIT_SUCCESS);

}

【命令行管道符案例】

       以ps -ef | grep "run"来举例功能:在ps -ef查找到的数据中过滤出含有run字符的所在行数据。

#include <stdio.h>

#include <stdlib.h>

#include <unistd.h>

#include <string.h>

#include <sys/wait.h>


int main()

{

int pipefd[2] = {-1};

    if (pipe(pipefd) < 0)

    {

        perror("pipe error");

        return -1;

    }

    //ps程序

    pid_t ps_pid = fork();

    if (ps_pid == 0)

    {

    //将标准输出重定向到管道的写端,将要打印的数据写到管道中

        dup2(pipefd[1], 1);

        //将该子进程替换成ps进程

        execlp("ps", "ps", "-ef", NULL);

        exit(0);

    }

    //grep程序

    pid_t grep_pid = fork();

    if (grep_pid == 0)

    {

    //关闭写端,防止读完数据后发生阻塞

        close(pipefd[1]);

        //将标准输入重定向到管道的读端,从0-标准输入读取的数据相当于从管道读取数据

        dup2(pipefd[0], 0);

        //将该子进程替换成grep进程 grep ssh

        execlp("grep", "grep", "run", NULL);

        exit(0);

    }

    //关闭父进程的读取端

    close(pipefd[0]);

    close(pipefd[1]);

    waitpid(ps_pid, NULL, 0);

    waitpid(grep_pid, NULL, 0);

   /* 我的第一个命令行管道符 C 程序 */

   printf("stdout Hello, World! \n");

   return 0;

}


评论
© c++小牛钱小白 | Powered by LOFTER