📅  最后修改于: 2023-12-03 14:56:10.631000             🧑  作者: Mango
在Unix系统中,fork()
是非常重要的系统调用之一。它用于创建一个新的进程,这个新进程是原进程的一个副本,但是它运行在一个新的地址空间里。pipe()
是另一个重要的系统调用,它创建一个管道,可以在不同的进程之间传递数据。
让我们来编写一个C程序,演示如何使用fork()
和pipe()
系统调用。
下面是我们希望程序的功能:
首先,我们需要包含相关的头文件:
#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()
系统调用来实现进程间通讯。我们通过在父进程中写入数据,然后在子进程中读取数据并将其打印到终端上来演示了这个过程。