本文主要是介绍8.28练习,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
使用两个有名管道实现双向通信
使用两个有名管道(FIFO)实现双向通信。父进程负责写入信息到管道,子进程负责从管道读取信息并显示到终端上。使用信号处理来确保进程在接收到 “quit” 命令时正确退出。
进程A
#include <myhead.h>// 信号处理函数,收到信号时退出
void handle_signal(int sig) {exit(EXIT_SUCCESS);
}int main(int argc, const char *argv[]) {signal(SIGTERM, handle_signal); // 注册信号处理函数pid_t pid;pid = fork();if (pid > 0) { // 父进程, 发送信息char buff[1024];int send = open("./path1", O_WRONLY);if (send == -1) {perror("open send");return -1;}while (1) {memset(buff, 0, sizeof(buff));int len = read(0, buff, sizeof(buff));write(send, buff, len); // 写入管道if (strcmp(buff, "quit\n") == 0) {kill(getpid(), SIGTERM); // 通知子进程退出break;}}close(send);exit(EXIT_SUCCESS);} else if (pid == 0) { // 子进程,读取信息char buff[1024];int receive = open("./path2", O_RDONLY);if (receive == -1) {perror("open receive");return -1;}while (1) {memset(buff, 0, sizeof(buff));int len = read(receive, buff, sizeof(buff)); // 读取管道数据write(1, buff, len);if (strcmp(buff, "quit\n") == 0) {kill(getppid(), SIGTERM); // 通知父进程退出break;}}close(receive);exit(EXIT_SUCCESS);} else {perror("fork");return -1;}return 0;
}
进程B
#include <myhead.h>// 信号处理函数,收到信号时退出
void handle_signal(int sig) {exit(EXIT_SUCCESS);
}int main(int argc, const char *argv[]) {signal(SIGTERM, handle_signal); // 注册信号处理函数pid_t pid;pid = fork();if (pid > 0) { // 父进程, 发送信息char buff[1024];int send = open("./path2", O_WRONLY);if (send == -1) {perror("open send");return -1;}while (1) {memset(buff, 0, sizeof(buff));int len = read(0, buff, sizeof(buff));write(send, buff, len); // 写入管道if (strcmp(buff, "quit\n") == 0) {kill(getpid(), SIGTERM); // 通知子进程退出break;}}close(send);exit(EXIT_SUCCESS);} else if (pid == 0) { // 子进程,读取信息char buff[1024];int receive = open("./path1", O_RDONLY);if (receive == -1) {perror("open receive");return -1;}while (1) {memset(buff, 0, sizeof(buff));int len = read(receive, buff, sizeof(buff)); // 读取管道数据write(1, buff, len);if (strcmp(buff, "quit\n") == 0) {kill(getppid(), SIGTERM); // 通知父进程退出break;}}close(receive);exit(EXIT_SUCCESS);} else {perror("fork");return -1;}return 0;
}
代码解释
进程A
-
信号处理函数:
void handle_signal(int sig) {exit(EXIT_SUCCESS); }
- 当接收到
SIGTERM
信号时,进程会调用handle_signal
函数并退出。
- 当接收到
-
注册信号处理函数:
signal(SIGTERM, handle_signal);
- 注册
SIGTERM
信号的处理函数。
- 注册
-
创建子进程:
pid_t pid; pid = fork();
-
父进程(发送信息):
if (pid > 0) {// 打开管道int send = open("./path1", O_WRONLY);// 读取标准输入并写入管道while (1) {int len = read(0, buff, sizeof(buff));write(send, buff, len);if (strcmp(buff, "quit\n") == 0) {kill(getpid(), SIGTERM); // 通知子进程退出break;}}close(send);exit(EXIT_SUCCESS); }
-
子进程(读取信息):
else if (pid == 0) {// 打开管道int receive = open("./path2", O_RDONLY);// 从管道读取数据并显示到终端while (1) {int len = read(receive, buff, sizeof(buff));write(1, buff, len);if (strcmp(buff, "quit\n") == 0) {kill(getppid(), SIGTERM); // 通知父进程退出break;}}close(receive);exit(EXIT_SUCCESS); }
进程B
-
信号处理函数:
void handle_signal(int sig) {exit(EXIT_SUCCESS); }
- 当接收到
SIGTERM
信号时,进程会调用handle_signal
函数并退出。
- 当接收到
-
注册信号处理函数:
signal(SIGTERM, handle_signal);
- 注册
SIGTERM
信号的处理函数。
- 注册
-
创建子进程:
pid_t pid; pid = fork();
-
父进程(发送信息):
if (pid > 0) {// 打开管道int send = open("./path2", O_WRONLY);// 读取标准输入并写入管道while (1) {int len = read(0, buff, sizeof(buff));write(send, buff, len);if (strcmp(buff, "quit\n") == 0) {kill(getpid(), SIGTERM); // 通知子进程退出break;}}close(send);exit(EXIT_SUCCESS); }
-
子进程(读取信息):
else if (pid == 0) {// 打开管道int receive = open("./path1", O_RDONLY);// 从管道读取数据并显示到终端while (1) {int len = read(receive, buff, sizeof(buff));write(1, buff, len);if (strcmp(buff, "quit\n") == 0) {kill(getppid(), SIGTERM); // 通知父进程退出break;}}close(receive);exit(EXIT_SUCCESS); }
运行步骤
-
创建命名管道:
#include<myhead.h> int main (int argc, const char *argv[]) {if(mkfifo("./path1",0644)==-1){perror("path1");return -1;}if(mkfifo("./path2",0644)==-1){perror("path2");return -1;}return 0; }
-
编译两个程序:
gcc usr2.c -o u1 gcc usr2.c -o u2
-
分别在两个终端窗口中运行两个程序:
./u1
和
./u2
总结
这篇博客展示了如何使用两个有名管道实现双向通信。父进程负责写入信息到管道,子进程负责从管道读取信息并显示到终端上。还使用了信号处理来确保进程在接收到 “quit” 命令时正确退出。
这篇关于8.28练习的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!