8.28练习

2024-08-29 03:36
文章标签 练习 8.28

本文主要是介绍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

  1. 信号处理函数

    void handle_signal(int sig) {exit(EXIT_SUCCESS);
    }
    
    • 当接收到 SIGTERM 信号时,进程会调用 handle_signal 函数并退出。
  2. 注册信号处理函数

    signal(SIGTERM, handle_signal);
    
    • 注册 SIGTERM 信号的处理函数。
  3. 创建子进程

    pid_t pid;
    pid = fork();
    
  4. 父进程(发送信息)

    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);
    }
    
  5. 子进程(读取信息)

    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

  1. 信号处理函数

    void handle_signal(int sig) {exit(EXIT_SUCCESS);
    }
    
    • 当接收到 SIGTERM 信号时,进程会调用 handle_signal 函数并退出。
  2. 注册信号处理函数

    signal(SIGTERM, handle_signal);
    
    • 注册 SIGTERM 信号的处理函数。
  3. 创建子进程

    pid_t pid;
    pid = fork();
    
  4. 父进程(发送信息)

    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);
    }
    
  5. 子进程(读取信息)

    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);
    }
    

运行步骤

  1. 创建命名管道:

    #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;
    }
    
  2. 编译两个程序:

    gcc usr2.c -o u1
    gcc usr2.c -o u2
    
  3. 分别在两个终端窗口中运行两个程序:

    ./u1
    

    ./u2
    

总结

这篇博客展示了如何使用两个有名管道实现双向通信。父进程负责写入信息到管道,子进程负责从管道读取信息并显示到终端上。还使用了信号处理来确保进程在接收到 “quit” 命令时正确退出。

这篇关于8.28练习的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1116726

相关文章

RabbitMQ练习(AMQP 0-9-1 Overview)

1、What is AMQP 0-9-1 AMQP 0-9-1(高级消息队列协议)是一种网络协议,它允许遵从该协议的客户端(Publisher或者Consumer)应用程序与遵从该协议的消息中间件代理(Broker,如RabbitMQ)进行通信。 AMQP 0-9-1模型的核心概念包括消息发布者(producers/publisher)、消息(messages)、交换机(exchanges)、

【Rust练习】12.枚举

练习题来自:https://practice-zh.course.rs/compound-types/enum.html 1 // 修复错误enum Number {Zero,One,Two,}enum Number1 {Zero = 0,One,Two,}// C语言风格的枚举定义enum Number2 {Zero = 0.0,One = 1.0,Two = 2.0,}fn m

MySql 事务练习

事务(transaction) -- 事务 transaction-- 事务是一组操作的集合,是一个不可分割的工作单位,事务会将所有的操作作为一个整体一起向系统提交或撤销请求-- 事务的操作要么同时成功,要么同时失败-- MySql的事务默认是自动提交的,当执行一个DML语句,MySql会立即自动隐式提交事务-- 常见案例:银行转账-- 逻辑:A给B转账1000:1.查询

html css jquery选项卡 代码练习小项目

在学习 html 和 css jquery 结合使用的时候 做好是能尝试做一些简单的小功能,来提高自己的 逻辑能力,熟悉代码的编写语法 下面分享一段代码 使用html css jquery选项卡 代码练习 <div class="box"><dl class="tab"><dd class="active">手机</dd><dd>家电</dd><dd>服装</dd><dd>数码</dd><dd

014.Python爬虫系列_解析练习

我 的 个 人 主 页:👉👉 失心疯的个人主页 👈👈 入 门 教 程 推 荐 :👉👉 Python零基础入门教程合集 👈👈 虚 拟 环 境 搭 建 :👉👉 Python项目虚拟环境(超详细讲解) 👈👈 PyQt5 系 列 教 程:👉👉 Python GUI(PyQt5)文章合集 👈👈 Oracle数据库教程:👉👉 Oracle数据库文章合集 👈👈 优

如何快速练习键盘盲打

盲打是指在不看键盘的情况下进行打字,这样可以显著提高打字速度和效率。以下是一些练习盲打的方法: 熟悉键盘布局:首先,你需要熟悉键盘上的字母和符号的位置。可以通过键盘图或者键盘贴纸来帮助记忆。 使用在线打字练习工具:有许多在线的打字练习网站,如Typing.com、10FastFingers等,它们提供了不同难度的练习和测试。 练习基本键位:先从学习手指放在键盘上的“家位”开始,通常是左手的

anaconda3下的python编程练习-csv翻译器

相关理解和命令 一、环境配置1、conda命令2、pip命令3、python命令 二、开发思路三、开发步骤 一、环境配置 1、conda命令 镜像源配置 conda config --show channels //查看镜像源conda config --remove-key channels //删除添加源,恢复默认源#添加镜像源conda config --ad

推荐练习键盘盲打的网站

对于初学者来说,以下是一些推荐的在线打字练习网站: 打字侠:这是一个专业的在线打字练习平台,提供科学合理的课程设置和个性化学习计划,适合各个水平的用户。它还提供实时反馈和数据分析,帮助你提升打字速度和准确度。 dazidazi.com:这个网站提供了基础的打字练习,适合初学者从零开始学习打字。 Type.fun打字星球:提供了丰富的盲打课程和科学的打字课程设计,还有诗词歌赋、经典名著等多样

综合DHCP、ACL、NAT、Telnet和PPPoE进行网络设计练习

描述:企业内网和运营商网络如上图所示。 公网IP段:12.1.1.0/24。 内网IP段:192.168.1.0/24。 公网口PPPOE 拨号采用CHAP认证,用户名:admin 密码:Admin@123 财务PC 配置静态IP:192.168.1.8 R1使用模拟器中的AR201型号,作为交换路由一体机,下图的WAN口为E0/0/8口,可以在该接口下配置IP地址。 可以通过

JAVA学习-练习试用Java实现“删除有序数组中的重复项”

问题: 给你一个有序数组 nums ,请你 原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。 不要使用额外的数组空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。 说明: 为什么返回数值是整数,但输出的答案是数组呢? 请注意,输入数组是以「引用」方式传递的,这意味着在函数里修改输入数组对于调用者是可见的。 你可以想象内部操作如下