📜  演示fork()和pipe()的C程序(1)

📅  最后修改于: 2023-12-03 14:56:10.631000             🧑  作者: Mango

演示fork()和pipe()的C程序

在Unix系统中,fork()是非常重要的系统调用之一。它用于创建一个新的进程,这个新进程是原进程的一个副本,但是它运行在一个新的地址空间里。pipe()是另一个重要的系统调用,它创建一个管道,可以在不同的进程之间传递数据。

让我们来编写一个C程序,演示如何使用fork()pipe()系统调用。

程序功能

下面是我们希望程序的功能:

  1. 父进程创建一个子进程。
  2. 父进程将一些数据写入到管道中。
  3. 子进程从管道中读取数据。
  4. 子进程将读取到的数据打印到终端上。
代码实现

首先,我们需要包含相关的头文件:

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

接着,我们定义一些常量和变量:

#define BUF_SIZE 1024
#define STR_SIZE 128

char *message = "Hello, world!";
char read_buffer[BUF_SIZE];

BUF_SIZE表示我们在管道中使用的缓冲区大小,STR_SIZE表示我们使用的字符串大小。message是我们希望将其写入管道的字符串,read_buffer是我们从管道中读取数据存储的缓冲区。

现在,我们可以创建一个管道了:

int fd[2];
if (pipe(fd) == -1) {
    perror("pipe");
    exit(EXIT_FAILURE);
}

pipe()系统调用返回一个包含两个文件描述符的数组,第一个描述符用于读取数据,第二个描述符用于写入数据。如果出现错误,会返回-1,并打印错误信息。

接下来,我们使用fork()系统调用创建一个子进程:

pid_t pid = fork();
if (pid == -1) {
    perror("fork");
    exit(EXIT_FAILURE);
}

如果出现错误,fork()系统调用会返回-1,并打印错误信息。

现在,我们需要在父进程和子进程中分别实现不同的操作。

在父进程中,我们将数据写入管道中:

if (pid > 0) {  // Parent process
    close(fd[0]);  // Close the read end of the pipe

    // Write data to the pipe
    if (write(fd[1], message, strlen(message)) != strlen(message)) {
        perror("write");
        exit(EXIT_FAILURE);
    }
    close(fd[1]);  // Close the write end of the pipe

    // Wait for the child process to exit
    wait(NULL);
    exit(EXIT_SUCCESS);
}

在子进程中,我们从管道中读取数据,并将其打印到终端上:

else if (pid == 0) {  // Child process
    close(fd[1]);  // Close the write end of the pipe

    // Read data from the pipe
    int n = read(fd[0], read_buffer, BUF_SIZE);
    if (n == -1) {
        perror("read");
        exit(EXIT_FAILURE);
    }
    read_buffer[n] = '\0';  // Null-terminate the string

    printf("Child process received message: %s\n", read_buffer);
    close(fd[0]);  // Close the read end of the pipe

    exit(EXIT_SUCCESS);
}

我们先关闭写端口,然后读取管道中的数据到read_buffer中,并打印到终端上。

最后,在main()函数中,我们将上述代码结合起来:

int main()
{
    int fd[2];
    if (pipe(fd) == -1) {
        perror("pipe");
        exit(EXIT_FAILURE);
    }

    pid_t pid = fork();
    if (pid == -1) {
        perror("fork");
        exit(EXIT_FAILURE);
    }

    char *message = "Hello, world!";
    char read_buffer[BUF_SIZE];

    if (pid > 0) {  // Parent process
        close(fd[0]);  // Close the read end of the pipe

        // Write data to the pipe
        if (write(fd[1], message, strlen(message)) != strlen(message)) {
            perror("write");
            exit(EXIT_FAILURE);
        }
        close(fd[1]);  // Close the write end of the pipe

        // Wait for the child process to exit
        wait(NULL);
        exit(EXIT_SUCCESS);
    } else if (pid == 0) {  // Child process
        close(fd[1]);  // Close the write end of the pipe

        // Read data from the pipe
        int n = read(fd[0], read_buffer, BUF_SIZE);
        if (n == -1) {
            perror("read");
            exit(EXIT_FAILURE);
        }
        read_buffer[n] = '\0';  // Null-terminate the string

        printf("Child process received message: %s\n", read_buffer);
        close(fd[0]);  // Close the read end of the pipe

        exit(EXIT_SUCCESS);
    }
    return 0;
}
总结

在本篇文章中,我们学习了如何使用fork()pipe()系统调用。

fork()系统调用用于创建一个新的进程,这个新进程是原进程的一个副本,但是它运行在一个新的地址空间里。

pipe()系统调用用于创建一个管道,可以在不同的进程之间传递数据。

我们编写了一个C程序,用于演示如何使用fork()pipe()系统调用来实现进程间通讯。我们通过在父进程中写入数据,然后在子进程中读取数据并将其打印到终端上来演示了这个过程。