报文和消息队列又是进程间通行的一种手段(用于发送大量信息,它没有信号那种异步性和命名管道很像,能发送接收大量数据,但管道的缺点是数据没有组织性)。
它的特点,他的生命周期很长,一个消息队列创建后,让他消亡的方式有2种:
1.从启系统,整个内存的刷新。
2.自己手动销毁他。
说他克服了数据组织问题,我们知道一个管道,你在1点写了一些数据,读进程没有去读。你2点时候又写了一批数据,那么这2批数据就会合在一起,你无法区分它们中间的断点在哪儿。消息队列不同之处在于它克服了这一点,至于他是如何区分2块数据的,这就根据客户指定的type,看到具体代码。
[root@liumengli MSG]# cat send_msg.c (这里是发送消息的代码)
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#define BUFF_LEN 1024
#define RET_ERROR 1
#define RET_OK 0
typedef struct msg_send_struct { //这就是一个消息的数据结构
long my_type; //我们就是根据这个字段来区分每块消息的
char my_text[BUFF_LEN];
} msg_send_struct;
int main() {
char * path = "/";
int i_porject_id = 7;
key_t key;
msg_send_struct msg_send; //定义发送消息
int i_ret;
int i_msg_id;
int i_flag = 0666|IPC_CREAT; //为消息管道的创建指定参数,IPC_CREAT表示这个消息队列是创建,而不是搜索已经存在的消息队列
key = ftok(path, i_porject_id);//为消息队列生成一个key,当然你也可以手动指定,当你运气很好没有和已经窜在的消息队列的key起冲突的时候
if(key == 1) {
printf("building key error\n");
exit(1);
}
i_msg_id = msgget(key, i_flag);//根据你的参数决定是创建还是搜索KEY值得消息队列
if(i_msg_id == -1) {
printf("create msg queue error\n");
exit(1);
}
printf("i_msg_id = %d\n", i_msg_id);
msg_send.my_type = 1;
strcpy(msg_send.my_text, "hello world"); //初始化消息
i_ret = msgsnd(i_msg_id, &msg_send, strlen("hello world") + 1, IPC_NOWAIT);//开始发送,nowait表示如果队列中消息满了当前进程不等待直接返回错误,反之很容易理解吧
if(i_ret == -1) {
printf("msg send error\n");
exit(1);
}
exit(0);
}
[root@liumengli MSG]# cat rec_msg.c (接收消息的代码)
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#define BUFF_LEN 1024
#define RET_ERROR 1
#define RET_OK 0
typedef struct msg_rec_struct {//和前面一样
long my_type;
char my_text[BUFF_LEN];
} msg_rec_struct;
int main() {
char * path = "/";
int i_project_id = 7;
key_t key;
int i_ret;
int i_msg_id;
int i_flag = IPC_EXCL;//这个就和上面的CRATE差距了,EXCL是搜索,找不到是会出错的
msg_rec_struct msg_rec;
key = ftok(path, i_project_id);//生成KEY值,放心打印后你会发现2个KEY值是相同的
if(key == -1) {
printf("building key error\n");
exit(1);
}
i_msg_id = msgget(key, i_flag);//首先找到队列
if(i_msg_id == -1) {
printf("create msg queue error\n");
exit(1);
}
printf("i_msg_id = %d\n", i_msg_id);
i_ret = msgrcv(i_msg_id, &msg_rec, BUFF_LEN, 1, 0);//获取消息队列中的消息,注意我们第4个参数是1,他的意思是我们要去my_type是1的消息,因为我们在发送中,把发送消息的mytype设置的是1
if(i_ret == -1) {
printf("recive message error\n");
exit(1);
}
printf("recive message: %s\n", msg_rec.my_text);
msgctl(i_msg_id, IPC_RMID, NULL);//这个是销毁消息队列
}
[root@liumengli MSG]# ./send_msg
i_msg_id = 98304
[root@liumengli MSG]# ./rec_msg
i_msg_id = 98304
recive message: hello world
[root@liumengli MSG]#
下面就是我们的运行了,我们看到,我们成功的把hello world的字符串从send_msg发送到了rec_msg,当然你可以在shell里面用指令去销毁这个队列,命令是ipcrm -q (消息队列的ID)我么销毁,看看会发生什么。
[root@liumengli MSG]# ./send_msg
i_msg_id = 131072
[root@liumengli MSG]# ipcrm -q 131072
[root@liumengli MSG]# ./rec_msg
create msg queue error
可以看出在搜索是否有131072这个队列时候就出错误了。最后补充下权限,队列不是随随便便就能访问的,内核在实现的时候加了权限限制。
1.超级用户可以访问任何队列,只要你能得到队列的KEY值即可。
2.普通用户只能访问同组人或者自己的队列.
分享到:
相关推荐
这资源是在linux下用C语言开发的模拟ATM机开户、取款与款的源代码(这是服务器端代码,客户器比较简单,...主要应用了Linux多线程,Select监听,还有Linux与Window之间应用Socket与消息队列并行通行的交互基础框架...
5. **事件队列**:如`System.Threading.QueueUserWorkItem`可以用来在进程间传递信息,通过队列异步执行任务。 6. **.NET Remoting**:虽然在.NET Core中已被弃用,但在.NET Framework中,.NET Remoting提供了一种...
通常,我们可以通过多种算法来解决这个问题,其中之一就是使用队列的广度优先搜索(BFS)策略。在这个方法中,队列作为数据结构扮演着关键角色,帮助我们系统地探索迷宫的所有可能路径。 迷宫问题的基本设定是一个...
交通基础设施的通行能力是衡量交通基础设施的重要指标之一。它是指交通基础设施在一定时间内能够容纳和处理的交通流量。通行能力的评估对交通基础设施的设计、规划和管理有着重要的影响。美国道路通行能力手册HCM...
### 道路通行能力计算方法 #### 一、道路通行能力概述 道路通行能力是指在特定条件下(包括但不限于交通条件、道路条件等),单位时间内道路上所能通过的最大交通量。这一概念对于道路建设和管理至关重要,它直接...
在解谜过程中,开发者可能首先创建一个表示迷宫的二维数组,每个位置代表一个节点,可以是墙或可通行的空间。然后,利用栈或队列进行搜索。 对于栈的DFS实现,通常会用一个辅助栈来存储当前路径,每次进入一个新...
队列在任务调度、打印作业、多进程通信等方面有广泛应用。 迷宫问题是一个典型的图搜索问题,通常可以利用栈或队列来解决。在这个问题中,我们有一张表示为二维数组的迷宫,每个单元格可能是障碍(墙)、可通行或...
美国通行能力手册(Highway Capacity Manual,简称HCM)是智能交通和智慧交通从业者的重要参考资料,它是一本详细论述交通概念的手册,由美国国家研究委员会下属的交通研究委员会(Transportation Research Board,...
每一步的探索结果都会被压入栈或队列中,当某条路径无法通行时,再从栈或队列中弹出之前的探索结果,回到上一个节点继续尝试其他方向。 #### 四、程序实现 **数据结构定义**: 1. **迷宫表示**:采用二维数组`...
1. 初始化一个全连通的迷宫,所有墙都是可通行的。 2. 使用队列进行BFS,每次随机选择一个未访问的相邻格子并标记为已访问,连接两个格子,然后将新格子入队。 3. 当所有格子都被访问过时,迷宫生成完成。 ### 4. ...
- 对于当前节点的每一个相邻节点(上、下、左、右),如果该节点未被访问且是可通行的,将其加入队列,并标记为已访问。 3. 如果队列为空但仍未找到目标节点,说明没有路径可以从起点到终点,算法结束。 在VC/C++...
三位通行+ 三位通行+汉字通行证,注册.exe
假设有一个隧道,隧道内部可以容纳多辆汽车通行,而这些汽车就像消息一样,按照先后顺序进入隧道,并依次离开。这种先进先出的原则,实际上与Android中的消息队列机制非常相似。 #### 二、Android消息队列机制详解 ...
根据给定的信息,本文将对“c++用队列实现迷宫代码”的核心知识点进行详细的解析,包括迷宫的创建、迷宫的遍历搜索算法(广度优先搜索BFS)、队列在算法中的应用以及如何展示迷宫的路径。 ### 一、迷宫创建 在程序...
根据提供的信息来看,这篇文章主要涉及的是“瑞星通行证”及其使用方法的相关知识点。瑞星通行证是一种用于登录瑞星软件或服务的身份验证工具,通常由一系列字符组成,包括字母、数字等混合排列。以下是对该通行证...
通过计算两者之差,可以得知算法执行所需的时间。 回文判断通常使用栈来实现,其基本思想是将字符串的前半部分依次压入栈中,然后逐一弹出并与后半部分进行比较。如果两者完全匹配,那么这个字符串就是回文。不过,...
【通行证整合方案】 通行证整合方案是一种技术方法,用于在多个不同的系统或平台上实现单点登录(Single Sign-On, SSO)的功能。通过这种方式,用户在一个系统登录后,可以在其他关联的系统中自动登录,无需重复...
操作系统进程管理是操作系统中最重要的组件之一,它负责管理计算机系统中的进程资源,确保系统的稳定性和高效性。本习题集涵盖了操作系统进程管理的主要概念和技术,包括进程同步、进程通信、进程调度、存储器管理等...
在计算机科学领域,特别是操作系统理论中,PV操作是用于控制并发进程之间互斥与同步的关键机制之一。PV操作(也称作信号量操作)是由荷兰科学家Edsger W. Dijkstra提出的一种原子性操作,主要包括两种类型:P操作...