8.29练习

2024-08-30 07:52
文章标签 练习 8.29

本文主要是介绍8.29练习,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

进程间通信示例

使用消息队列在两个独立的 C 程序之间进行进程间通信。每个程序都包含父进程和子进程,父进程用于写消息到消息队列,子进程用于从消息队列读取消息。

程序1 (s1.c)

#include <myhead.h> // 定义消息缓冲区结构体
struct msgbuf {long mtype; // 消息类型char mtext[1000]; // 消息正文
};#define LENG (sizeof(struct msgbuf) - sizeof(long)) // 计算消息正文的长度int main() {key_t key1 = ftok("./", 'A'); // 创建key值1key_t key2 = ftok("./", 'B'); // 创建key值2if (key1 == -1 || key2 == -1) {perror("ftok"); return -1;}int msgID1 = msgget(key1, IPC_CREAT | 0664); // 创建或获取消息队列1int msgID2 = msgget(key2, IPC_CREAT | 0664); // 创建或获取消息队列2if (msgID1 == -1 || msgID2 == -1) {perror("msgget"); return -1;}pid_t pid = fork(); // 创建子进程if (pid > 0) {// 父进程发送消息到队列1struct msgbuf send;while (1) {printf("s1父进程:请输入消息类型:\n");scanf("%ld", &send.mtype); // 读取消息类型getchar(); // 清除输入缓冲区中的换行符printf("s1父进程:请输入消息的内容:\n");fgets(send.mtext, sizeof(send.mtext), stdin); // 读取消息内容send.mtext[strlen(send.mtext) - 1] = '\0'; // 去掉换行符msgsnd(msgID1, &send, LENG, 0); // 发送消息到队列1printf("s1父进程:发送消息:类型=%ld,内容=%s\n", send.mtype, send.mtext);if (strcmp(send.mtext, "quit") == 0) { // 如果消息内容是"quit",则退出循环break;}}// 等待子进程结束wait(NULL);// 删除消息队列1if (msgctl(msgID1, IPC_RMID, NULL) == -1) {perror("msgctl"); return -1;}printf("s1父进程:消息队列1已删除\n");} else if (pid == 0) {// 子进程读取消息从队列2struct msgbuf rcv;while (1) {msgrcv(msgID2, &rcv, LENG, 0, 0); // 从队列2读取消息,第一个0:读取第一个信息不论类型,第二个0:阻塞接收printf("s1子进程:收到消息:类型=%ld,内容=%s\n", rcv.mtype, rcv.mtext);if (strcmp(rcv.mtext, "quit") == 0) { // 如果消息内容是"quit",则退出循环break;}}printf("s1子进程:退出\n");exit(0); // 子进程退出} else {perror("fork"); return -1;}return 0;
}

程序2 (s2.c)

#include <myhead.h> // 包含自定义头文件
// 定义消息缓冲区结构体
struct msgbuf {long mtype; // 消息类型char mtext[1000]; // 消息正文
};#define LENG (sizeof(struct msgbuf) - sizeof(long)) // 计算消息正文的长度int main() {key_t key1 = ftok("./", 'A'); // 创建key值1key_t key2 = ftok("./", 'B'); // 创建key值2if (key1 == -1 || key2 == -1) {perror("ftok"); return -1;}int msgID1 = msgget(key1, IPC_CREAT | 0664); // 创建或获取消息队列1int msgID2 = msgget(key2, IPC_CREAT | 0664); // 创建或获取消息队列2if (msgID1 == -1 || msgID2 == -1) {perror("msgget"); return -1;}pid_t pid = fork(); // 创建子进程if (pid > 0) {// 父进程发送消息到队列2struct msgbuf send;while (1) {printf("s2父进程:请输入消息类型:\n");scanf("%ld", &send.mtype); // 读取消息类型getchar(); // 清除输入缓冲区中的换行符printf("s2父进程:请输入消息的内容:\n");fgets(send.mtext, sizeof(send.mtext), stdin); // 读取消息内容send.mtext[strlen(send.mtext) - 1] = '\0'; // 去掉换行符msgsnd(msgID2, &send, LENG, 0); // 发送消息到队列2printf("s2父进程:发送消息:类型=%ld,内容=%s\n", send.mtype, send.mtext);if (strcmp(send.mtext, "quit") == 0) { // 如果消息内容是"quit",则退出循环break;}}// 等待子进程结束wait(NULL);// 删除消息队列2if (msgctl(msgID2, IPC_RMID, NULL) == -1) {perror("msgctl"); return -1;}printf("s2父进程:消息队列2已删除\n");} else if (pid == 0) {// 子进程读取消息从队列1struct msgbuf rcv;while (1) {msgrcv(msgID1, &rcv, LENG, 0, 0); // 从队列1读取消息,第一个0:读取第一个信息不论类型,第二个0:阻塞接收printf("s2子进程:收到消息:类型=%ld,内容=%s\n", rcv.mtype, rcv.mtext);if (strcmp(rcv.mtext, "quit") == 0) { // 如果消息内容是"quit",则退出循环break;}}printf("s2子进程:退出\n");exit(0); // 子进程退出} else {perror("fork"); return -1;}return 0;
}

解释

  1. 定义消息缓冲区结构体

    struct msgbuf {long mtype; // 消息类型char mtext[1000]; // 消息正文
    };
    
  2. 计算消息正文的长度

    #define LENG (sizeof(struct msgbuf) - sizeof(long))
    
  3. 主函数

    • 使用 ftok 生成两个唯一的键值。
    • 使用 msgget 创建或获取两个消息队列。
    • 使用 fork 创建子进程。
  4. 父进程发送消息

    • 父进程负责发送消息到消息队列。
    • 循环读取用户输入的消息类型和消息正文,并发送到消息队列。
    • 如果消息正文是 “quit”,则退出循环并等待子进程结束。
    • 删除消息队列。
  5. 子进程读取消息

    • 子进程负责从消息队列中读取消息。
    • 循环接收消息队列中的消息,并打印消息类型和消息正文。
    • 如果消息正文是 “quit”,则退出循环。

这两个程序,每个程序都包含父进程和子进程,父进程用于写消息到消息队列,子进程用于从消息队列中读取消息,实现了两个程序之间的进程间通信。

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



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

相关文章

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) 额外空间的条件下完成。 说明: 为什么返回数值是整数,但输出的答案是数组呢? 请注意,输入数组是以「引用」方式传递的,这意味着在函数里修改输入数组对于调用者是可见的。 你可以想象内部操作如下