C语言进程间通信:使用管道实现互斥写入和父进程读取
以下是使用C语言创建两个进程,互斥地向管道写数据,并在父进程中读取不同数据的示例代码:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
#define BUFFER_SIZE 25
#define READ_END 0
#define WRITE_END 1
int main(void)
{
char write_msg1[BUFFER_SIZE] = 'Hello from process 1!';
char write_msg2[BUFFER_SIZE] = 'Hello from process 2!';
char read_msg1[BUFFER_SIZE];
char read_msg2[BUFFER_SIZE];
int fd[2];
pid_t pid;
// Create the pipe
if (pipe(fd) == -1) {
fprintf(stderr, "Pipe failed");
return 1;
}
// Fork the first child process
pid = fork();
if (pid < 0) {
fprintf(stderr, "Fork failed");
return 1;
} else if (pid == 0) {
// Child process 1
// Close the unused write end of the pipe
close(fd[READ_END]);
// Write to the pipe
write(fd[WRITE_END], write_msg1, strlen(write_msg1) + 1);
// Close the write end of the pipe
close(fd[WRITE_END]);
exit(0);
} else {
// Fork the second child process
pid = fork();
if (pid < 0) {
fprintf(stderr, "Fork failed");
return 1;
} else if (pid == 0) {
// Child process 2
// Close the unused write end of the pipe
close(fd[READ_END]);
// Write to the pipe
write(fd[WRITE_END], write_msg2, strlen(write_msg2) + 1);
// Close the write end of the pipe
close(fd[WRITE_END]);
exit(0);
} else {
// Parent process
// Close the write end of the pipe
close(fd[WRITE_END]);
// Read from the pipe
read(fd[READ_END], read_msg1, BUFFER_SIZE);
read(fd[READ_END], read_msg2, BUFFER_SIZE);
// Close the read end of the pipe
close(fd[READ_END]);
printf("Message 1: %s\nMessage 2: %s\n", read_msg1, read_msg2);
// Wait for both child processes to finish
wait(NULL);
wait(NULL);
}
}
return 0;
}
在这个示例代码中,我们首先使用pipe()函数创建了一个管道,并创建了两个子进程。子进程1向管道写入一个消息,子进程2向管道写入另一个消息。在父进程中读取这两个消息并打印它们。注意到我们在父进程中调用了wait()函数,以等待两个子进程都结束。这样做是为了确保子进程完成它们的任务后,父进程才会继续执行。这样可以避免出现竞态条件(race condition)的情况。
代码说明:
- 创建管道:
pipe(fd)函数创建一个管道,并将管道的两个文件描述符存储在fd数组中。fd[0]是读端,fd[1]是写端。 - 创建子进程:
fork()函数创建一个子进程。子进程会继承父进程的代码和数据空间,包括管道文件描述符。 - 子进程写入: 子进程通过
write(fd[WRITE_END], ...)函数向管道写入数据。 - 父进程读取: 父进程通过
read(fd[READ_END], ...)函数从管道读取数据。 - 关闭文件描述符: 在不需要使用文件描述符时,应该使用
close()函数关闭它,以释放资源。 - 等待子进程: 父进程使用
wait(NULL)函数等待子进程结束。这可以避免父进程过早结束,导致子进程无法完成任务。
这个示例展示了使用管道实现进程间通信的基本方法。在实际应用中,可以根据具体需求修改代码,例如可以使用信号量或互斥量来实现更复杂的同步机制。
原文地址: https://www.cveoy.top/t/topic/nY1D 著作权归作者所有。请勿转载和采集!