`
memorymyann
  • 浏览: 270755 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

进程通行之报文消息队列

阅读更多

报文和消息队列又是进程间通行的一种手段(用于发送大量信息,它没有信号那种异步性和命名管道很像,能发送接收大量数据,但管道的缺点是数据没有组织性)。

 

它的特点,他的生命周期很长,一个消息队列创建后,让他消亡的方式有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与Window之间的Socket、消息队列通信

    这资源是在linux下用C语言开发的模拟ATM机开户、取款与款的源代码(这是服务器端代码,客户器比较简单,...主要应用了Linux多线程,Select监听,还有Linux与Window之间应用Socket与消息队列并行通行的交互基础框架...

    WPF本地进程间的通行

    5. **事件队列**:如`System.Threading.QueueUserWorkItem`可以用来在进程间传递信息,通过队列异步执行任务。 6. **.NET Remoting**:虽然在.NET Core中已被弃用,但在.NET Framework中,.NET Remoting提供了一种...

    迷宫问题用队列解决

    通常,我们可以通过多种算法来解决这个问题,其中之一就是使用队列的广度优先搜索(BFS)策略。在这个方法中,队列作为数据结构扮演着关键角色,帮助我们系统地探索迷宫的所有可能路径。 迷宫问题的基本设定是一个...

    美国道路通行能力手册HCM2010

    交通基础设施的通行能力是衡量交通基础设施的重要指标之一。它是指交通基础设施在一定时间内能够容纳和处理的交通流量。通行能力的评估对交通基础设施的设计、规划和管理有着重要的影响。美国道路通行能力手册HCM...

    道路通行能力计算方法

    ### 道路通行能力计算方法 #### 一、道路通行能力概述 道路通行能力是指在特定条件下(包括但不限于交通条件、道路条件等),单位时间内道路上所能通过的最大交通量。这一概念对于道路建设和管理至关重要,它直接...

    栈和队列迷宫

    在解谜过程中,开发者可能首先创建一个表示迷宫的二维数组,每个位置代表一个节点,可以是墙或可通行的空间。然后,利用栈或队列进行搜索。 对于栈的DFS实现,通常会用一个辅助栈来存储当前路径,每次进入一个新...

    数据结构(C语言版) 栈与队列 迷宫问题

    队列在任务调度、打印作业、多进程通信等方面有广泛应用。 迷宫问题是一个典型的图搜索问题,通常可以利用栈或队列来解决。在这个问题中,我们有一张表示为二维数组的迷宫,每个单元格可能是障碍(墙)、可通行或...

    美国通行能力手册 中文版

    美国通行能力手册(Highway Capacity Manual,简称HCM)是智能交通和智慧交通从业者的重要参考资料,它是一本详细论述交通概念的手册,由美国国家研究委员会下属的交通研究委员会(Transportation Research Board,...

    数据结构上机实验_栈和队列的应用_迷宫问题 (含代码和报告)

    每一步的探索结果都会被压入栈或队列中,当某条路径无法通行时,再从栈或队列中弹出之前的探索结果,回到上一个节点继续尝试其他方向。 #### 四、程序实现 **数据结构定义**: 1. **迷宫表示**:采用二维数组`...

    C语言使用队列和栈实现自动生成和求解迷宫

    1. 初始化一个全连通的迷宫,所有墙都是可通行的。 2. 使用队列进行BFS,每次随机选择一个未访问的相邻格子并标记为已访问,连接两个格子,然后将新格子入队。 3. 当所有格子都被访问过时,迷宫生成完成。 ### 4. ...

    VC/c++平台队列实现迷宫算法

    - 对于当前节点的每一个相邻节点(上、下、左、右),如果该节点未被访问且是可通行的,将其加入队列,并标记为已访问。 3. 如果队列为空但仍未找到目标节点,说明没有路径可以从起点到终点,算法结束。 在VC/C++...

    三位通行 三位通行+汉字通行证,注册.exe

    三位通行+ 三位通行+汉字通行证,注册.exe

    从现实生活中理解android_线程消息机制

    假设有一个隧道,隧道内部可以容纳多辆汽车通行,而这些汽车就像消息一样,按照先后顺序进入隧道,并依次离开。这种先进先出的原则,实际上与Android中的消息队列机制非常相似。 #### 二、Android消息队列机制详解 ...

    c++用队列写的迷宫代码

    根据给定的信息,本文将对“c++用队列实现迷宫代码”的核心知识点进行详细的解析,包括迷宫的创建、迷宫的遍历搜索算法(广度优先搜索BFS)、队列在算法中的应用以及如何展示迷宫的路径。 ### 一、迷宫创建 在程序...

    瑞星通行证及帐号绝对可用

    根据提供的信息来看,这篇文章主要涉及的是“瑞星通行证”及其使用方法的相关知识点。瑞星通行证是一种用于登录瑞星软件或服务的身份验证工具,通常由一系列字符组成,包括字母、数字等混合排列。以下是对该通行证...

    栈和队列:迷宫、回文判断.docx

    通过计算两者之差,可以得知算法执行所需的时间。 回文判断通常使用栈来实现,其基本思想是将字符串的前半部分依次压入栈中,然后逐一弹出并与后半部分进行比较。如果两者完全匹配,那么这个字符串就是回文。不过,...

    通行证整合方案通行证整合方案通行证整合方案

    【通行证整合方案】 通行证整合方案是一种技术方法,用于在多个不同的系统或平台上实现单点登录(Single Sign-On, SSO)的功能。通过这种方式,用户在一个系统登录后,可以在其他关联的系统中自动登录,无需重复...

    操作系统 进程管理习题

    操作系统进程管理是操作系统中最重要的组件之一,它负责管理计算机系统中的进程资源,确保系统的稳定性和高效性。本习题集涵盖了操作系统进程管理的主要概念和技术,包括进程同步、进程通信、进程调度、存储器管理等...

    如何用PV原语实现进程间的互斥与同步

    在计算机科学领域,特别是操作系统理论中,PV操作是用于控制并发进程之间互斥与同步的关键机制之一。PV操作(也称作信号量操作)是由荷兰科学家Edsger W. Dijkstra提出的一种原子性操作,主要包括两种类型:P操作...

Global site tag (gtag.js) - Google Analytics