多进程开发实现ls |wc -l

 

这段代码实现了一个父子进程间的通信,模拟了在Linux终端中执行"ps aux | grep xxx"命令的过程。以下是代码的主要思路:

  1. 创建管道:

    • 使用pipe系统调用创建一个管道,得到两个文件描述符,fd[0]用于读取,fd[1]用于写入。
  2. 创建子进程:

    • 使用fork系统调用将程序分成父进程(pid > 0)和子进程(pid == 0)。
  3. 父进程职责:

    • 关闭管道的写入端(fd[1]),因为父进程将从管道中读取数据。
    • 从管道的读入端(fd[0])读取数据。
    • 对从子进程接收到的数据进行过滤和处理(在此代码中,简单地打印)。
  4. 子进程职责:

    • 关闭管道的读取端(fd[0]),因为子进程将向管道中写入数据。
    • 将标准输出(STDOUT_FILENO)重定向到管道的写入端(fd[1])。
    • 执行"ps aux"命令,使其输出写入到管道中。
  5. 清理和同步:

    • 父进程使用wait系统调用等待子进程完成。
    • 代码中使用perror进行错误处理,打印错误消息。
/*
    实现 ps aux | grep xxx 父子进程间通信

    子进程: ps aux, 子进程结束后,将数据发送给父进程
    父进程:获取到数据,过滤
    pipe()
    execlp()
    子进程将标准输出 stdout_fileno 重定向到管道的写端。  dup2
*/

#include 
#include 
#include 
#include 
#include 
#include 

int main() {

    // 创建一个管道
    int fd[2];
    int ret = pipe(fd);

    if(ret == -1) {
        perror("pipe");
        exit(0);
    }

    // 创建子进程
    pid_t pid = fork();

    if(pid > 0) {
        // 父进程
        // 关闭写端
        close(fd[1]);
        // 从管道中读取
        char buf[1024] = {0};

        int len = -1;
        while((len = read(fd[0], buf, sizeof(buf) - 1)) > 0) {
            // 过滤数据输出
            printf("%s", buf);
            memset(buf, 0, 1024);
        }

        wait(NULL);

    } else if(pid == 0) {
        // 子进程
        // 关闭读端
        close(fd[0]);

        // 文件描述符的重定向 stdout_fileno -> fd[1]
        dup2(fd[1], STDOUT_FILENO);
        // 执行 ps aux
        execlp("ps", "ps", "aux", NULL);
        perror("execlp");
        exit(0);
    } else {
        perror("fork");
        exit(0);
    }


    return 0;
}

你可能感兴趣的:(linux,运维,服务器,c++,算法)