进程和子进程笔记(Linux/C++)

                     

贡献者: admin; addis

1. exec 系列命令

   如果不改变环境变量也可以用 execv(),完整的例子如

#include <unistd.h>    // For execv()
#include <sys/wait.h>  // For wait()
#include <iostream>    // For std::cout
#include <cstdio>      // For perror()

int main() {
    // Define the command and its arguments
    char *args[] = {(char *)"/bin/ls",
        (char *)"-l", (char *)NULL};

    // Fork a new process
    pid_t pid = fork();

    if (pid == -1) {
        // Fork failed
        perror("fork failed");
        return 1;
    } else if (pid == 0) {
        std::cout << "running ls command" << std::endl;
        // Replace the child process with a new program (ls -l)
        execv("/bin/ls", args);
        // If execv() returns, an error occurred
        perror("execv failed");
        return 1;
    } else {
        // Parent process
        int status;
        // Wait for the child to complete. pid is now of the child process
        waitpid(pid, &status, 0);
        std::cout << "Child process finished with status: "
            << status << std::endl;
    }
}
该程若运行成功会把 ls 的输出打到 stdout。

2. pipe 管道编程

   写管道

#include <cstdio>
#include <cstdlib>
int main() {
    FILE* fp = popen("wc -w", "w");
    if (fp == nullptr) {
        perror("popen failed");
        exit(EXIT_FAILURE);
    }
    const char* input = "Hello, how many words are here?\n";
    fprintf(fp, "%s", input);
    pclose(fp);
    return 0;
}
读管道
FILE* fp = popen("ls -l", "r");
if (fp) {
    char buffer[128];
    while (fgets(buffer, sizeof(buffer), fp) != nullptr) {
        printf("%s", buffer);
    }
    int ret = pclose(fp);
    if (ret == -1) {
        perror("pclose failed");
        return -1;
    }
    int ret = WEXITSTATUS(ret);
}

   如果要同时读写管道,需要用 pipe()dup2()

#include <unistd.h>
#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main() {
    int pipe_stdin[2];  // Pipe for child's stdin
    int pipe_stdout[2]; // Pipe for child's stdout
    pid_t pid;

    // Create pipes
    if (pipe(pipe_stdin) == -1 || pipe(pipe_stdout) == -1) {
        perror("pipe failed");
        exit(EXIT_FAILURE);
    }
    // Fork a child process
    pid = fork();
    if (pid == -1) {
        perror("fork failed");
        exit(EXIT_FAILURE);
    }
    if (pid == 0) {
        // Child process

        // Redirect child's stdin to pipe_stdin[0]
        dup2(pipe_stdin[0], STDIN_FILENO);
        close(pipe_stdin[0]);
        close(pipe_stdin[1]);  // Close unused write end

        // Redirect child's stdout to pipe_stdout[1]
        dup2(pipe_stdout[1], STDOUT_FILENO);
        close(pipe_stdout[0]); // Close unused read end
        close(pipe_stdout[1]);

        // Execute the command
        // Replace 'cat' with your command
        execl("/bin/sh", "sh", "-c", "cat", NULL);

        // If execl fails
        perror("execl failed");
        exit(EXIT_FAILURE);
    }
    else {
        // Parent process
        close(pipe_stdin[0]);  // Close unused read end of stdin pipe
        close(pipe_stdout[1]); // Close unused write end of stdout pipe

        // Write to the child's stdin
        const char* input = "Hello, child process!\n";
        write(pipe_stdin[1], input, strlen(input));

        // Close stdin write end after writing
        close(pipe_stdin[1]);

        // Read the child's stdout
        char buffer[128];
        ssize_t count;
        while ((count = read(pipe_stdout[0],
            buffer, sizeof(buffer) - 1)) > 0) {
            buffer[count] = '\0';  // Null-terminate the buffer
            printf("Child output: %s", buffer);
        }

        close(pipe_stdout[0]); // Close stdout read end

        // Wait for the child to terminate
        wait(NULL);
    }
    return 0;
}


致读者: 小时百科一直以来坚持所有内容免费无广告,这导致我们处于严重的亏损状态。 长此以往很可能会最终导致我们不得不选择大量广告以及内容付费等。 因此,我们请求广大读者热心打赏 ,使网站得以健康发展。 如果看到这条信息的每位读者能慷慨打赏 20 元,我们一周就能脱离亏损, 并在接下来的一年里向所有读者继续免费提供优质内容。 但遗憾的是只有不到 1% 的读者愿意捐款, 他们的付出帮助了 99% 的读者免费获取知识, 我们在此表示感谢。

                     

友情链接: 超理论坛 | ©小时科技 保留一切权利