第二十五章 system v消息队列(一)
IPC对象的持续性
- 随进程持续 :一直存在直到打开的最后一个进程结束。(如pipe和FIFO)
- 随内核持续 :一直存在直到内核自举(内核自举就是把主引导记录加载到内存,并跳转执行这段内存)或显示删除(如System V消息队列、共享内存、信号量)
- 随文件系统持续 :一直存在直到显示删除,即使内核自举还存在。(POSIX消息队列、共享内存、信号量如果是使用映射文件来实现)
消息队列
- 消息队列提供了一种从一个进程向另外一个进程发送一块数据的方法
- 每个数据块都被认为是有一个类型,接受者进程接受的数据块可以有不同的类型值
- 管道所传输的数据是基于字节流的,数据与数据之间是没有边界的,所以通常称管道为流管道;接受数据的时候,遵守先进先出的原则。
- 消息队列传输的数据块是有类型的,通常把成为消息,消息与消息之间是有边界的;接受数据的时候,不一定要按照顺序的方式来接受(不一定要先进先出)
- 消息队列也有管道一样的不足,就是每个消息的最大长度是有限的(MSGMAX),每个消息队列的总的字节数是有限的(MSGMNB),系统上消息队列的总数也是有一个上限(MSGMNI)
IPC对象数据结构
内核为每个IPC对象维护一个数据结构
struct ipc_perm {
uid_t cuid; /* creator user ID */
gid_t cgid; /* creator group ID */
uid_t uid; /* owner user ID */
gid_t gid; /* owner group ID */
unsigned short mode; /* r/w permissions */
};
消息队列结构
struct msqid_ds {
struct ipc_perm msg_perm;
msgqnum_t msg_qnum; /* no of messages on queue */
msglen_t msg_qbytes; /* bytes max on a queue */
pid_t msg_lspid; /* PID of last msgsnd(2) call */
pid_t msg_lrpid; /* PID of last msgrcv(2) call */
time_t msg_stime; /* last msgsnd(2) time */
time_t msg_rtime; /* last msgrcv(2) time */
time_t msg_ctime; /* last change time */
};
消息队列在内核中的表示
消息队列函数
msgget
头文件
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
int msgget(key_t key, int msgflg);
作用:
创建或打开一个消息队列
参数:
key : 某个消息队列的名字
msgflg : 由9个权限标志构成,它们的用法和创建文件时使用的模式标志是一样的
返回值:
成功 : 返回一个非负整数,即消息队列的标识码
失败 : -1
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#define ERR_EXIT(m) \
do \
{ \
perror(m); \
exit(EXIT_FAILURE); \
} while (0)
int main(int argc, char const *argv[])
{
int msgid;
// 如果存在就打开,不存在就创建
// msgid = msgget(1234,0666 | IPC_CREAT);
// 如果不存在就创建,存在打开就报错
// msgid = msgget(1234,0666 | IPC_CREAT | IPC_EXCL);
//IPC_PRIVATE实际上等于0,当key为IPC_PRIVATE时,会创建一个新的消息队列,不能被其他进程共享;父子进程、兄弟进程可以共享,因为可以获取到msqid
// msgid = msgget(IPC_PRIVATE,0666 | IPC_CREAT | IPC_EXCL);
//指定了IPC_PRIVATE后,可以不加IPC_CREAT | IPC_EXCL
// msgid = msgget(IPC_PRIVATE,0666);
//如果消息队列已存在,可以直接打开
msgid = msgget(1234,0);
if(msgid == -1)
ERR_EXIT("msgget");
printf("msget success, msgid=%d\n!",msgid);
return 0;
}
msgctl
int msgctl(int msqid, int cmd, struct msqid_ds *buf);
作用:
控制消息队列
参数:
msqid : 由msgget函数返回的消息队列标识码
cmd : 将要采取的动作
IPC_STAT : 把msgid_ds结构中的数据设置为消息队列的当前关联值
IPC_SET : 在进程有足够权限的前提下,把消息队列的当前关联值设置为msgid_ds数据结构中给出的值
IPC_RMID : 删除消息队列
buf :
返回值:
成功 : 0
失败 : -1
IPC_RMID
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char const *argv[])
{
int msqid;
msqid = msgget(1234, 0);
if(msqid == -1)
{
perror("msgget error");
exit(EXIT_FAILURE);
}
printf("msqid : %d\n",msqid);
msgctl(msqid,IPC_RMID,NULL);
return 0;
}
IPC_STAT
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char const *argv[])
{
int msqid;
msqid = msgget(1234, 0);
if(msqid == -1)
{
perror("msgget error");
exit(EXIT_FAILURE);
}
printf("msqid : %d\n",msqid);
struct msqid_ds buf;
msgctl(msqid,IPC_STAT,&buf);
printf("mode : %o\n",buf.msg_perm.mode);
printf("bytes : %ld\n",buf.__msg_cbytes);
printf("number : %lu\n",buf.msg_qnum);
printf("msgmnb : %lu\n",buf.msg_qbytes);
return 0;
}
IPC_SET
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char const *argv[])
{
int msqid;
msqid = msgget(1234, 0);
if(msqid == -1)
{
perror("msgget error");
exit(EXIT_FAILURE);
}
printf("msqid : %d\n",msqid);
struct msqid_ds buf;
msgctl(msqid,IPC_STAT,&buf);
sscanf("600", "%o", (unsigned int*)&buf.msg_perm.mode);
msgctl(msqid, IPC_SET, &buf);
printf("mode : %o\n",buf.msg_perm.mode);
return 0;
}
其它
ipcs - 查看当前已打开的消息队列
ipcrm -S|-s key|semid - 删除打开的消息队列
ipcrm -q msqid - 删除打开的消息队列
ipcrm -Q 键 - 删除打开的消息队列(只能用于键不为0的)
第二十五章 system v消息队列(一)的更多相关文章
- 第二十六章 system v消息队列(二)
msgsnd int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg); 作用: 把一条消息添加到消息队列中 参数: msqi ...
- 第6章 System V消息队列
6.1 概述 System V消息队列在内核中是list存放的,头结点中有2个指针msg_first 和msg_last.其中每个节点包含:下个节点地址的指针.类型.长度.数据等. 6.2 函数 6. ...
- 第二十七章 system v消息队列(三)
消息队列实现回射客户/服务器 msg_srv.c #include <stdio.h> #include <stdlib.h> #include <unistd.h> ...
- 第二十九章 System V共享内存
共享内存数据结构 共享内存函数 shmget int shmget(key_t key, size_t size, int shmflg); 功能: 用于创建共享内存 参数: key : 这个共享内存 ...
- 进程间通信 System V 消息队列
1.msgget (key_t ket,int flag) ; //创建一个新的消息队列或者访问一个已存在的消息队列 2.msgsnd(int msid, const void *ptr ,size_ ...
- Linux进程通信之System V消息队列
System V消息队列是Open Group定义的XSI,不属于POSIX标准.System V IPC的历史相对很早,在上个世70年代后期有贝尔实验室的分支机构开发,80年代加入System V的 ...
- 利用System V消息队列实现回射客户/服务器
一.介绍 在学习UNIX网络编程 卷1时,我们当时可以利用Socket套接字来实现回射客户/服务器程序,但是Socket编程是存在一些不足的,例如: 1. 服务器必须启动之时,客户端才能连上服务端,并 ...
- UNIX环境高级编程——system V消息队列
unix早期通信机制中的信号能够传送的信息量有限,管道则只能传送无格式字节流,这远远是不够的. 消息队列(也叫报文队列)客服了这些缺点: 消息队列就是一个消息的链表. 可以把消 ...
- Gradle 1.12用户指南翻译——第二十五章. Scala 插件
其他章节的翻译请参见: http://blog.csdn.net/column/details/gradle-translation.html 翻译项目请关注Github上的地址: https://g ...
随机推荐
- MongoDB的全文索引
Table of Contents 背景 如何使用 准备工作:插入数据 建立全局索引 查询结果 使用中存在哪些问题? 英文存在停止词 中文无法采用全文索引 前面了解了多种索引方式,比如单键索引,多 ...
- Case1-basic network framework/Related organization‘s name
常见的计算机网络物理拓扑结构: 1.星型网 2.树型网 3.分布式网络 4.总线型网 5.环型网 6.复合型网络 计算机网络相关的标准化组织: 国际标准化组织(ISO):International O ...
- for循环用腻了,试试列表生成式。
在编写程序或者查看别人的程序时,经常会遇到列表生成式,这个使用起来并不复杂,但是非常有用,使我们的代码更加简洁灵活.很多python使用者并不太会使用它.今天,就给大家详细讲解列表生成式和生成器表达式 ...
- Redis开发与运维:linux安装
Linux 安装 我的系统是inux 系统,官网下载 https://redis.io/download redis-5.0.5.tar.gz 解压: 编译安装: 官网和文档说得已经很清楚了,现在就执 ...
- pycharm 2019/10 激活码 最新福利 (1)
MTW881U3Z5-eyJsaWNlbnNlSWQiOiJNVFc4ODFVM1o1IiwibGljZW5zZWVOYW1lIjoiTnNzIEltIiwiYXNzaWduZWVOYW1lIjoiI ...
- 计算几何基础算法几何C++实现
This file is implementation of Common Common Computational Geometry Algorithms.Please please pay att ...
- python常用算法学习(4)——数据结构
数据结构简介 1,数据结构 数据结构是指相互之间存在着一种或多种关系的数据元素的集合和该集合中数据元素之间的关系组成.简单来说,数据结构就是设计数据以何种方式组织并存贮在计算机中.比如:列表,集合与字 ...
- 写在Python学习前
Python是一门非常有意思的语言,不需要太多的语言基础,就可以实现自己想要的操作.许多非计算机专业的学生都可以利用词云分析.分词.画图等实现自己想要的东西.学习Python和学习其他语言一样,需要耐 ...
- Django跨域问题(CORS错误)
Django跨域问题(CORS错误) 一.出现跨域问题(cors错误)的原因 通常情况下,A网页访问B服务器资源时,不满足以下三个条件其一就是跨域访问 协议不同 端口不同 主机不同 二.Django解 ...
- 代码审计-DedeCMS-V5.7前台任意用户密码重置
0x01 漏洞影响 该漏洞允许攻击者修改任意前台用户密码. 0x02 漏洞利用条件 1,开启会员模块 2,攻击者拥有一个正常的会员账号 3,目标没有设置安全问题 0x03 漏洞分析 漏洞文件:/mem ...