System V IPC(1)-消息队列
一.概述
System V三种IPC:消息队列,信号量,共享内存。这三种IPC最先出现在AT&T System v UNIX上面,并遵循XSI标准,有时候也被称为XSI IPC。
本文先探讨消息队列:
1.消息队列允许进程以消息的形式交换数据。读写都是针对整条消息,不能读写消息的一部分,不像管道那样可以以流的形式读写任意字节。
2.消息队列除了包含数据外,还有一个整数来表示该消息的类型。读取消息的时候即可以按照先进先出方式读取,也可以按照消息类型来读取。
二.函数接口
1.创建一个消息队列
#include <sys/msg.h> int msgget(key_t key, int msgflg);
key:是一个整数,该函数会将key转换成一个IPC标识符。key有3种方法定义:1.手动随意指定一个整数。2.把IPC_PRIVATE当作key传入,系统会自动生成。3.用ftok()函数。
msgflg:指定该消息的权限,跟文件的权限控制类似。
2.发送消息
#include <sys/msg.h> int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
msqid:用msget()获取的id。
mgsp:存储消息的结构指针,下面的mtype就是自定义的消息类型,mtext是消息数据。
struct msgbuf {
long mtype; /* message type, must be > 0 */
]; /* message data */
};
msgsz:消息的大小,对应上面msgbuf里面的mtext。
msgflg:控制消息发送时异常状况,如消息队列满。
3.接收消息
#include <sys/msg.h> ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg);
msqid:用msget()获取的id,或者已知的消息ID。
msgp,msgsz:同msgsnd()。
msgtyp:接收消息的类型,即msgbuf里面的mtype。但还有别的用法:
如果为0,就获取队列中第一个可用消息。
大于0,获取相同类型消息的第一个,即mtype。
小于0,获取等于或小于mtype的绝对值第一个消息。等会我们一一做实验。
msgflg:同msgsnd()。
4.消息控制
#include <sys/msg.h> int msgctl(int msqid, int cmd, struct msqid_ds *buf);
cmd:有3个选项,IPC_STAT,IPC_SET,IPC_RMID。前2个是获取和设置msgid对应的消息结构体,最后一个是删除消息队列。
三.简单的例子
1.创建消息队列
/**
* @file msg_create.c
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/msg.h>
void err_exit(const char *err_msg)
{
printf("%s error\n", err_msg);
exit();
}
int main(void)
{
| IPC_CREAT);
)
err_exit("msgget()");
printf("create msg_id:%d\n", msg_id);
;
}
2.发送消息
/**
* @file msg_send.c
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/msg.h>
#define MAX_BUFFER 1024
typedef struct
{
long msg_type;
char msg_text[MAX_BUFFER];
} msg_t;
void err_exit(const char *err_msg)
{
printf("%s error\n", err_msg);
exit();
}
int main(int argc, char *argv[])
{
)
{
printf(]);
exit();
}
]);
msg_t send_msg;
];
int text_len = strlen(text);
send_msg.msg_type = atoi(argv[]);
memcpy((void *)send_msg.msg_text, text, text_len);
) == -)
err_exit("msgsnd()");
;
}
3.接收消息
/**
* @file msg_recv.c
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/msg.h>
#define MAX_BUFFER 1024
typedef struct
{
long msg_type;
char msg_text[MAX_BUFFER];
} msg_t;
void err_exit(const char *err_msg)
{
printf("%s error\n", err_msg);
exit();
}
int main(int argc, const char *argv[])
{
)
{
printf(]);
exit();
}
]);
msg_t recv_msg;
]);
) == -)
err_exit("msgrcv()");
printf("receive:%s\n", recv_msg.msg_text);
//if (msgctl(msg_id, IPC_RMID, 0) == -1)
// err_exit("msgctl()");
;
}
四.实验
1.创建消息,编译执行msg_create.c,用ipcs -q查看消息:

可以看到:msqid就是用IPC_PRIVATE当作key传入,系统会自动生成的,msqid=262144等会接收消息要用。perms是我们代码设置的权限,此时的消息字节和消息数都是0。
2.发送消息,编译执行msg_send.c,并发消息,用ipcs -q查看消息:

上面./mes_send后面依次是:刚刚创建的消息队列id,消息类型,消息数据。
接下来,我们再继续发送1条1类型消息,2条2类型消息,2条3类型消息,等会接收消息做实验。

现在我们有6条消息了。
3.接收消息,编译msg_recv.c。我们主要来实验msgrcv()里面的msg_type参数。即该文件的第36行代码。
3.1:当msg_type等于0时,获取队列中第一个可用消息。

可以看到,1234就是我刚刚第一次发送到该队列的消息。
3.2:当msg_type大于0,获取具有相同类型的第一个消息:

上面我们获取的是3类型的消息,接收的刚好是第一次发送3号消息的haha。
3.3:当msg_type小于0,获取等于或小于msg_type绝对值的第一个消息:

上面,-3的绝对值是3,而队列中存在最先放进去的消息是1号消息22222(本来是1号的1234,刚刚我们做实验时读取走了,所以剩下它第一)。1小于3,所以1号消息被读取。
4.消息队列的删除,msg_recv.c里面第41行代码,如果放开后编译执行,收到一条消息后整个队列全部删除。
System V IPC(1)-消息队列的更多相关文章
- System V IPC 之消息队列
消息队列和共享内存.信号量一样,同属 System V IPC 通信机制.消息队列是一系列连续排列的消息,保存在内核中,通过消息队列的引用标识符来访问.使用消息队列的好处是对每个消息指定了特定消息类型 ...
- 四十九、进程间通信——System V IPC 之消息队列
49.1 System V IPC 介绍 49.1.1 System V IPC 概述 UNIX 系统存在信号.管道和命名管道等基本进程间通讯机制 System V 引入了三种高级进程间通信机制 消息 ...
- Linux 系统编程 学习:04-进程间通信2:System V IPC(1)
Linux 系统编程 学习:04-进程间通信2:System V IPC(1) 背景 上一讲 进程间通信:Unix IPC-信号中,我们介绍了Unix IPC中有关信号的概念,以及如何使用. IPC的 ...
- Linux 系统编程 学习:05-进程间通信2:System V IPC(2)
Linux 系统编程 学习:05-进程间通信2:System V IPC(2) 背景 上一讲 进程间通信:System V IPC(1)中,我们介绍了System IPC中有关消息队列.共享内存的概念 ...
- 第3章 System V IPC
3.1 概述 System V IPC 包含:System V消息队列.System V信号量.System V共享内存. 3.2 key_t 键和 ftok函数 这三种类型的System V IPC ...
- 《Unix网络编程》卷2 读书笔记 第3章- System V IPC
1. 概述 三种类型的System V IPC:System V 消息队列.System V 信号量.System V 共享内存区 System V IPC在访问它们的函数和内核为它们维护的信息上共享 ...
- 从并发处理谈PHP进程间通信(二)System V IPC
.container { margin-right: auto; margin-left: auto; padding-left: 15px; padding-right: 15px } .conta ...
- System V IPC 之共享内存
IPC 是进程间通信(Interprocess Communication)的缩写,通常指允许用户态进程执行系列操作的一组机制: 通过信号量与其他进程进行同步 向其他进程发送消息或者从其他进程接收消息 ...
- System V IPC
1.概述 System V IPC共有三种类型:System V消息队列.System V 信号量.System V 共享内存区. System V IPC操作函数如下: 2.key_t键和ftok函 ...
随机推荐
- JAVA中的GC机制详解
优秀Java程序员必须了解的GC工作原理 一个优秀的Java程序员必须了解GC的工作原理.如何优化GC的性能.如何与GC进行有限的交互,因为有一些应用程序对性能要求较高,例如嵌入式系统.实时系统等,只 ...
- mysql经纬度查询并且计算2KM范围内附近用户的sql查询性能优化实例教程
之前很傻很天真地以为无非就是逐个计算距离,然后比较出来就行了,然后当碰到访问用户很多,而且数据库中经纬度信息很多的时候,计算量的迅速增长,能让服务器完全傻逼掉,还是老前辈的经验比我们丰富,给了我很大的 ...
- ArcGIS server 开发实践之【FeatureLayer类】
全是干活,你值得拥有 要素图层类简介:Class:FeatureLayer //调用方式:require(["esri/layers/FeatureLayer"],function ...
- WPF中的Invoke
今天帮同事看一个问题,她用为了实现动画效果用主线程执行Thread.Sleep,然后界面就卡死了. 这个问题好解决,new 一个Thread就行了,但是更新WPF的界面需要主线程的操作,然后习惯性的打 ...
- CSS 选择器 关系
常见的基于关系的选择器 选择器 选择的元素 A E 元素A的任一后代元素E (后代节点指A的子节点,子节点的子节点,以此类推) A > E 元素A的任一子元素E(也就是直 ...
- Android中的Interpolator
Android中的Interpolator Interpolator用于动画中的时间插值,其作用就是把0到1的浮点值变化映射到另一个浮点值变化. 本文列出Android API提供的Interpola ...
- Android studio 使用SVN需要忽略的文件
Android Studio创建的Android项目一般需要忽略 1..idea文件夹 2..gradle文件夹 3.所有的build文件夹 4.所有的.iml文件 5.local.propertie ...
- Android项目编译和使用C语言动态库(so库)
编译SO库 1.新建工程,建立jni目录用于放置c语言相关文件 2.编写Android.mk文件 LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) ...
- IOS开发——01_第一个OC程序
本文目录 一.新建Xcode项目 二.运行项目 注:建议先学习C语言, 如果你还没有编程经验,看不懂的地方可以在评论区提出,本文使用的为Xcode6.1版本,与之前版本会有所差异,但总体不变. 另:还 ...
- Android 加载大图片到内存
本文演示android中图片加载到内存 首先设计界面: 代码如下: <LinearLayout xmlns:android="http://schemas.android.com/ap ...