消息队列 (msgget, msgsnd, msgrcv, msgctl)的使用

如何使用 ftok 函数生成消息队列、共享内存或信号量所需的唯一标识符(键值) 

#include <sys/types.h>
#include <sys/ipc.h>
#include <stdio.h>

int main()
{
//声明两个 key_t 类型的变量 key1 和 key2。key_t 是一个整数类型,用于表示键值。
	key_t key1,key2;
//ftok 函数用于根据文件路径和项目标识符生成一个唯一的键值。
//ftok(".", 10) 和 ftok(".", 20) 分别生成了两个不同的键值,
//"." 表示当前目录,10 和 20 是项目标识符,保证生成不同的键值。
	key1 = ftok(".",10);
	key2 = ftok(".",20);
	printf("key1 = %d\n",key1);
	printf("key2 = %d\n",key2);
}

ftok 函数详解:

ftok 函数的作用是根据给定的文件路径和项目标识符生成一个唯一的 key_t 值,这个键值在创建消息队列、共享内存、信号量时作为标识符。该键值确保在同一系统中,不同的程序能够通过该键值来识别同一个资源。

key_t ftok(const char *pathname, int proj_id); 
  • pathname:指定用于生成 key_t 的文件路径。一般来说,我们可以选择现有的文件路径。为了避免影响文件系统,通常选择当前目录 "." 或某个特定的路径。
  • proj_id:一个项目标识符,用于区分不同的资源。它通常是一个整数值(如 1020)。即使文件路径相同,只要 proj_id 不同,ftok 生成的键值也会不同。

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <stdio.h>

int main()
{
	key_t key1,key2;
	int msgid1,msgid2;
	
	//1. 申请消息队列的key值
	key1 = ftok(".",10);
	key2 = ftok(".",20);
	printf("key1 = %d\n",key1);
	printf("key2 = %d\n",key2);
	
	//2. 根据key值申请ID号
	msgid1 = msgget(key1,IPC_CREAT|0666);
	printf("msgid1 = %d\n",msgid1);
	
	msgid2 = msgget(key2,IPC_CREAT|0666);
	printf("msgid2 = %d\n",msgid2);
	
	return 0;
}

  1. msgid1 = msgget(key1, IPC_CREAT | 0666);

    • msgget 函数用于获取或创建一个消息队列。如果消息队列已经存在,它会返回一个消息队列的 ID。如果消息队列不存在,它会根据 key1 创建一个新的消息队列。
    • IPC_CREAT 是一个标志,表示如果消息队列不存在,则创建一个新的消息队列。0666 是权限位,表示消息队列的访问权限。0666 表示所有用户均可读写消息队列。
    • msgid1 保存创建或获取的消息队列 ID。msgid2 = msgget(key2, IPC_CREAT | 0666);
    • 同上,根据 key2 创建或获取第二个消息队列,msgid2 保存第二个消息队列的 ID。
  • msgget该函数用于创建或访问一个消息队列,返回一个消息队列的标识符(ID)。

    int msgget(key_t key, int msgflg);
    
    • key:消息队列的键值(由 ftok 函数生成)。
    • msgflg:控制消息队列创建或访问的标志,常用标志包括:
      • IPC_CREAT:如果消息队列不存在,则创建一个新的消息队列。
      • IPC_EXCL:和 IPC_CREAT 一起使用,表示如果消息队列已存在则返回错误。
      • 0666:指定消息队列的访问权限。

利用消息队列 (msgget, msgsnd, msgrcv, msgctl) 实现进程间通信(IPC)的基本操作

发送消息程序 (msgsend.c

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>

// 定义消息的结构体
struct msgbuf {
    long mtype;       // 消息类型(必须为正整数)
    char mtext[50];   // 消息内容
};

int main() {
    key_t key;
    int msgid, ret;
    
    // 0. 定义消息变量,并赋值
    struct msgbuf buf;
    buf.mtype = 10;  // 设置消息类型为10
    bzero(&(buf.mtext), 50);  // 清空消息内容
    strcpy(buf.mtext, "hello"); // 设置消息内容为 "hello"
    
    // 1. 获取消息队列的 key 值
    key = ftok(".", 10);  // 使用当前目录和项目标识符10生成key
    printf("key = %d\n", key);
    
    // 2. 根据 key 值获取消息队列的 ID
    msgid = msgget(key, IPC_CREAT | 0666);  // 创建消息队列并设置权限
    printf("msgid : %d\n", msgid);
    
    // 3. 将数据发送到消息队列中
    ret = msgsnd(msgid, &buf, strlen(buf.mtext), 0);  // 发送消息
    if (ret == -1) {
        printf("msgsnd error!\n");
        exit(1);
    }
    
    return 0;
}

msgsnd(msgid, &buf, strlen(buf.mtext), 0): 向消息队列发送一条消息,mtype 是消息类型,mtext 是消息内容。strlen(buf.mtext) 用于传递消息内容的长度。

接收消息程序 (msgrcv.c)

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>

// 定义消息的结构体
struct msgbuf {
    long mtype;       // 消息类型(必须为正整数)
    char mtext[50];   // 消息内容
};

int main() {
    key_t key;
    int msgid;
    int ret;
    struct msgbuf buf;
    bzero(&(buf.mtext), 50);
    
    // 1. 获取消息队列的 key 值
    key = ftok(".", 10);  // 使用当前目录和项目标识符10生成key
    printf("key = %d\n", key);
    
    // 2. 根据 key 值获取消息队列的 ID
    msgid = msgget(key, IPC_CREAT | 0666);  // 获取消息队列ID
    printf("msgid : %d\n", msgid);
    
    // 3. 从消息队列接收数据
    ret = msgrcv(msgid, &buf, sizeof(buf.mtext), 10, 0);  // 接收指定类型的消息
    if (ret < 0) {
        printf("msgrcv error!\n");
    }
    
    // 打印接收到的消息内容
    printf("buf.mtext = %s\n", buf.mtext);
    
    // 4. 删除消息队列
    msgctl(msgid, IPC_RMID, NULL);  // 删除消息队列
    return 0;
}
  • msgrcv(msgid, &buf, sizeof(buf.mtext), 10, 0): 从消息队列接收消息,指定接收类型为 10并将接收到的消息存储在 buf.mtextsizeof(buf.mtext) 表示接收消息的最大长度。msgrcv 会阻塞等待消息,直到接收到指定类型的消息。
  • msgctl(msgid, IPC_RMID, NULL): 删除消息队列。

关键点总结:

  1. 消息队列的创建与访问

    • 通过 ftok() 获取一个唯一的键值(key)。
    • 通过 msgget() 使用 key 获取或创建消息队列。
  2. 发送消息

    • 使用 msgsnd() 将消息发送到消息队列。消息由 mtype(类型)和 mtext(内容)组成。
  3. 接收消息

    • 使用 msgrcv() 从消息队列中接收消息,消息根据 mtype 被选取。
  4. 删除消息队列

    • 使用 msgctl() 删除消息队列。

注意事项:

  • 消息队列通过 mtype 字段区分消息类型,这样接收方可以根据需要接收特定类型的消息。
  • msgsnd()msgrcv() 都会返回 -1 表示出错,需检查返回值进行错误处理。
  • msgctl() 中的 IPC_RMID 用来删除消息队列,但通常在使用完消息队列之后执行。

这样,父子进程之间可以通过消息队列实现数据传输。

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/949421.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Unity中 Xlua使用整理(一)

1.安装: 从GitHub上下载Xlua源码 Tencent/xLua: xLua is a lua programming solution for C# ( Unity, .Net, Mono) , it supports android, ios, windows, linux, osx, etc. (github.com) 下载Xlua压缩包&#xff0c;并解压将Aseet文件夹中的Xlua和Plugins文件夹复制到Unit…

Matlab仿真径向受压圆盘光弹图像

Matlab仿真径向受压圆盘光弹图像-十步相移法 主要参数 % 定义圆盘参数 R 15; % 圆盘半径&#xff0c;单位&#xff1a;mm h 5; % 圆盘厚度&#xff0c;单位&#xff1a;mm P 300; % 径向受压载荷大小&#xff0c;单位&#xff…

基于Django的学校智能图书馆借书归还订阅管理系统

完整源码项目包获取→点击文章末尾名片&#xff01;

【设计模式-2】23 种设计模式的分类和功能

在软件工程领域&#xff0c;设计模式是解决常见设计问题的经典方案。1994 年&#xff0c;Erich Gamma、Richard Helm、Ralph Johnson 和 John Vlissides&#xff08;四人帮&#xff0c;GoF&#xff09;在《设计模式&#xff1a;可复用面向对象软件的基础》一书中系统性地总结了…

阿里云代理商热销产品推荐

在数字化浪潮的推动下&#xff0c;企业对于云计算的依赖日益加深。阿里云&#xff0c;作为中国领先的云计算服务提供商&#xff0c;为企业提供了丰富多样的云产品和服务。本文将聚焦于阿里云代理商热销产品推荐&#xff0c;探讨其如何帮助企业高效利用云资源&#xff0c;加速数…

[redux] 异步逻辑的两种写法

createAsyncThunk | Redux Toolkit 第一种, extraReducers 普通的reducers只能写同步代码 异步必须得用中间件的形式,就是异步代码调用完有结果了, 再调用同步的reducer, 大概这么理解, 第一种怎么用呢? 先用一个异步函数 const fetchUserById createAsyncThunk(users/fet…

在Java中使用有符号类型模拟无符号整数的技巧

有符号整数和无符号整数 有符号整数&#xff1a;可以表示正数、负数和零。例如&#xff0c;Java中的 byte 类型是有符号的&#xff0c;其范围是 -128 到 127.无符号整数&#xff1a;只能表示非负数&#xff08;即零和正数&#xff09;。例如&#xff0c;无符号 byte 应该表示的…

51单片机——8*8LED点阵

LED 点阵的行则为发光二极管的阳极&#xff0c;LED 点阵的列则为发光二极管的阴极 根据 LED 发光二极管导通原理&#xff0c;当阳极为高电平&#xff0c;阴极为低电平则点亮&#xff0c;否则熄灭。 因此通过单片机P0口可控制点阵列&#xff0c;74HC595可控制点阵行 11 脚 SR…

Flutter:邀请海报,Widget转图片,保存相册

记录下&#xff0c;把页面红色区域内的内容&#xff0c;转成图片后保存到相册的功能 依赖 # 生成二维码 qr_flutter: ^4.1.0 # 保存图片 image_gallery_saver_plus: ^3.0.5view import package:demo/common/index.dart; import package:ducafe_ui_core/ducafe_ui_core.dart; i…

C++Primer const限定符

欢迎阅读我的 【CPrimer】专栏 专栏简介&#xff1a;本专栏主要面向C初学者&#xff0c;解释C的一些基本概念和基础语言特性&#xff0c;涉及C标准库的用法&#xff0c;面向对象特性&#xff0c;泛型特性高级用法。通过使用标准库中定义的抽象设施&#xff0c;使你更加适应高级…

C语言 游动的小球

代码如下&#xff1a; 在这里插入代码片#include<stdio.h> #include<stdlib.h> #include<windows.h>int main() {int i,j;int x 5;int y 10;int height 20;int velocity_x 1;int velocity_y 1;int left 0;int right 20;int top 0;int bottom 10;while(1){…

动漫推荐系统django+vue前台后台完整源码

完整源码项目包获取→点击文章末尾名片&#xff01;

Chapter 1 Understanding Large Language Models

文章目录 Understanding Large Language ModelsWhat is an LLM?Applications of LLMSStages of building and using LLMsUsing LLMS for different tasksA closer look at the GPT architectureBuilding a large language modelSummary Understanding Large Language Models …

什么是VLAN?

VLAN&#xff08;Virtual Local Area Network&#xff0c;虚拟局域网&#xff09;是一种将物理局域网划分成多个逻辑上独立的虚拟网络的技术。VLAN不依赖于设备的物理位置&#xff0c;而是通过逻辑划分&#xff0c;将局域网内的设备虚拟地组织到同一组。这种技术允许网络管理员…

【君正T31开发记录】12.编译工具相关总结及介绍

移植交叉工具包的时候&#xff0c;发现这是很多工具的集合包&#xff1b;以及写makefile的时候&#xff0c;也需要了解下这些工具的作用及用法&#xff0c;这里总结记录一下常见的工具及相关用法。 g C编译器&#xff0c;用于编译C源代码文件&#xff0c;这个很常见&#xff0…

Appium(一)--- 环境搭建

一、Android自动化环境搭建 1、JDK 必须1.8及以上(1) 安装&#xff1a;默认安装(2) 环境变量配置新建JAVA_HOME:安装路径新建CLASSPath%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tools.jar在path中增加&#xff1a;%JAVA_HOME%\bin;%JAVA_HOME%\jre\bin&#xff1b;(3) 验证…

猫的眼睛有几种颜色?

在猫咪神秘而迷人的世界里&#xff0c;它们的眼睛犹如璀璨星辰&#xff0c;闪烁着各异的光芒&#xff0c;颜色丰富多样&#xff0c;令人着迷。 猫眼睛的颜色&#xff0c;粗略一数&#xff0c;常见的便有黄色、蓝色、绿色、棕色&#xff0c;还有那神秘的异瞳。这些色彩并非无端生…

PHP框架+gatewayworker实现在线1对1聊天--接收消息(7)

文章目录 接收消息的原理接收消息JavaScript代码 接收消息的原理 接收消息&#xff0c;就是接受服务器转发的客户端消息。并不需要单独创建函数&#xff0c;因为 ws.onmessage会自动接收消息。我们需要在这个函数里进行处理。因为初始化的时候&#xff0c;已经处理的init类型的…

校园周边美食探索及分享平台的设计与实现(源码+数据库+文档)

亲测完美运行带论文&#xff1a;文末获取源码 文章目录 项目简介&#xff08;论文摘要&#xff09;运行视频包含的文件列表&#xff08;含论文&#xff09;前台运行截图后台运行截图 项目简介&#xff08;论文摘要&#xff09; &#xff1a; 美食一直是与人们日常生活息息相关…

基于深度学习的视觉检测小项目(七) 开始组态界面

开始设计和组态画面。 • 关于背景和配色 在组态画面之前&#xff0c;先要确定好画面的风格和色系。如果有前端经验和美术功底&#xff0c;可以建立自己的配色体系。像我这种工科男&#xff0c;就只能从网络上下载一些别人做好的优秀界面&#xff0c;然后在photo shop中抠取色…