IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 系统运维 -> 【C++服务器入门基础------5.IPC进程间通信--消息队列】 -> 正文阅读

[系统运维]【C++服务器入门基础------5.IPC进程间通信--消息队列】

大学生寒假在家过于无聊,整理一下以前学过的知识,顺便复习一下,水平较低,专业性差,仅供参考,不喜勿喷(反正也没人看)。封校两周,估计一旦解封我就不见了哈哈哈。

一、什么是消息队列

·消息队列提供了一个从一个进程向另外一个进程发送一块数据的方法

·每个数据块都被认为是有一个类型,接收者进程接收的数据块可以有不同的类型值

·消息队列也有管道一样的不足,就是每个数据块的最大长度是有上限的,系统上全体队列的最大总长度也有一个上限

消息队列是消息的链表,存放在内核中并由消息队列标识符表示。内核为每个IPC对象维护了一个数据结构struct ipc_perm,用于标识消息队列,让进程知道当前操作的是哪个消息队列。每一个msqid_ds表示一个消息队列,并通过msqid_ds.msg_first、msg_last维护一个先进先出的msg链表队列,当发送一个消息到该消息队列时,把发送的消息构造成一个msg的结构对象,并添加到msqid_ds.msg_first、msg_last维护的链表队列。

二、函数

包含头文件:<sys/msg.h><sys/types.h>和<sys/ipc.h>

int msgget(key_t key, int msgflg);

msgsnd(int msqid, struct msgbuf *msgp, size_t msgsz, int msgflg);

msgrcv(int msqid, struct msgbuf *msgp, size_t msgsz, ??long msg_typ, int msgflg);

int msgctl(int msqid, int cmd, struct msqid_ds *buf);

(1)msgget函数

作用

用来创建和访问一个消息队列

原型

int ?msgget(key_t key, int msgflg);

参数

key: 某个消息队列的名字

msgflg:由九个权限标志构成,它们的用法和创建文件时使用的mode模式标志是一样的

如果操作成功,msgget将返回一个非负整数,即该消息队列的标识码;如果失败,则返回“-1”

(2)msgsnd函数

作用

把一条消息添加到消息队列里去

原型

int ?msgsnd(int msgid,const void *msg_ptr,size_t msg_sz,int msgflg);

参数

msgid: 由msgget函数返回的消息队列标识码

msg_ptr:是一个指针,指针指向准备发送的消息,

msg_sz:是msg_ptr指向的消息长度,这个长度不能保存消息类型的那个“long int”长整型计算在内

msgflg:控制着当前消息队列满或到达系统上限时将要发生的事情

操作成功,返回“0”,如果失败,则返回“-1”

msgflg=IPC_NOWAIT表示队列满不等待,返回EAGAIN错误。

消息结构在两方面受到制约。首先,它必须小于系统规定的上限值;其次,它必须以一个“long int”长整数开始,接收者函数将利用这个长整数确定消息的类型

最好把消息结构定义为下面这个样子:

struct msgbuf {

long ?mtype;

char mtext[1];

}

?

(3)msgrcv函数

作用

是从一个消息队列里检索消息

原型

int ?msgrcv(int msgid, void *msg_ptr,size_t msgsz,long int msgtype,int msgflg);

参数

msgid: 由msgget函数返回的消息队列标识码

msg_ptr:是一个指针,指针指向准备接收的消息,

msgsz:是msg_ptr指向的消息长度,这个长度不能保存消息类型的那个“long int”长整型计算在内

msgtype:它可以实现接收优先级的简单形式

msgflg:控制着队列中没有相应类型的消息可供接收时将要发生的事

操作成功,返回实际放到接收缓冲区里去的字符个数,如果失败,则返回“-1”

msgtype=0返回队列第一条信息

msgtype>0返回队列第一条类型等于msgtype的消息 

msgtype<0返回队列第一条类型小于等于msgtype绝对值的消息 

msgflg=IPC_NOWAIT,队列没有可读消息不等待,返回ENOMSG错误。

msgflg=MSG_NOERROR,消息大小超过msgsz时被截断

msgtype>0且msgflg=MSC_EXCEPT,接收类型不等于msgtype的第一条消息。

(4)msgctl函数

作用

消息队列的控制函数,与共享内存的控制函数很相似

原型

int ?msgctl(int msqid,int command,strcut msqid_ds *buf);

参数

msqid: 由msgget函数返回的消息队列标识码

command:是将要采取的动作,(有三个可取值)

如果操作成功,返回“0”;如果失败,则返回“-1”

command:将要采取的动作(有三个可取值),分别如下:

三、代码实例

两个程序利用消息队列交替发收消息

第一个程序

#include<iostream>
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/msg.h>
#include<string.h>
#include <unistd.h>
#include<stdlib.h>
#include <stdio.h>
using namespace std;
struct wrmsgbuf {
    long mtype;//取消息的时候用
    char mtext[50];//具体的消息
};
int main()//写
{
    struct wrmsgbuf buf;
    int msg_id = 0;
    //创建消息队列
    msg_id = msgget((key_t)1001, IPC_CREAT | 0777);

    if (msg_id == -1)
    {
        perror("message create error");
        return 0;
    }


    while (true)
    {
        buf.mtype = 1;
        cin >> buf.mtext;//控制台输入
        if (msgsnd(msg_id, &buf, sizeof(buf), 0) == -1)//发送
        {
            perror("1message send error");
            return 0;
        }
        bzero(&buf, sizeof(buf));

        if (msgrcv(msg_id, &buf, sizeof(buf), 2, 0) == -1)//接受
        {
            perror("2message recieve error");
            return 0;
        }
        cout << " buf " << buf.mtext << endl;
    }


    return 0;
}

?

第二个程序

#include<iostream>
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/msg.h>
#include<string.h>
#include <unistd.h>
#include<stdlib.h>
#include <stdio.h>
using namespace std;
struct remsgbuf {
    long mtype;//取消息的时候用
    char mtext[50];//具体的消息
};
int main()//写
{
    struct remsgbuf buf;
    int msg_id = 0;
    //创建消息队列
    msg_id = msgget((key_t)1001, IPC_CREAT | 0777);

    if (msg_id == -1)
    {
        perror("message create error");
        return 0;
    }

    while (true)
    {
        if (msgrcv(msg_id, &buf, sizeof(buf), 1, 0) == -1)//接受
        {
            perror("1message recieve error");
            return 0;
        }
        cout << " buf " << buf.mtext << endl;

        buf.mtype = 2;
        cin >> buf.mtext;//控制台输入
        if (msgsnd(msg_id, &buf, sizeof(buf), 0) == -1)//发送
        {
            perror("2message send error");
            return 0;
        }
        bzero(&buf, sizeof(buf));

       
    }



    return 0;
}

执行结果

?

?

  系统运维 最新文章
配置小型公司网络WLAN基本业务(AC通过三层
如何在交付运维过程中建立风险底线意识,提
快速传输大文件,怎么通过网络传大文件给对
从游戏服务端角度分析移动同步(状态同步)
MySQL使用MyCat实现分库分表
如何用DWDM射频光纤技术实现200公里外的站点
国内顺畅下载k8s.gcr.io的镜像
自动化测试appium
ctfshow ssrf
Linux操作系统学习之实用指令(Centos7/8均
上一篇文章      下一篇文章      查看所有文章
加:2022-02-24 15:44:33  更:2022-02-24 15:46:12 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/16 5:39:56-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码