Linux进程间通信(消息队列)

可以用命令“ipcs”查看三种 IPC,“ipcrm”删除 IPC 对象。在 i.MX6ULL 终结者开发板终端输入“ipcs” 查看系统中存在的 IPC 信息: 

Linux进程间通信(消息队列)_第1张图片

这些 IPC 对象存在于内核空间,应用层使用 IPC 通信的步骤为: 

 Linux进程间通信(消息队列)_第2张图片

 1. 获取 key 值,内核会将 key 值映射成 IPC 标识符,获取 key 值常用方法:

(1)在 get 调用中将 IPC_PRIVATE 常量作为 key 值。

(2)使用 ftok()生成 key

2. 执行 IPC get 调用,通过 key 获取整数 IPC 标识符 id,每个 id 表示一个 IPC 对 

 3. 通过 id 访问 IPC 对象。

 4. 通过 id 控制 IPC 对

 

创建这三种 IPC 对象都要先获取 key 值,然后根据 key 获取 id,用到的函数如下:

Linux进程间通信(消息队列)_第3张图片

 下面介绍消息队列:

消息队列是类 unix 系统中一种数据传输的机制,其他操作系统中也实现了这种机制,可见这种通信机 制在操作系统中有重要地位。

Linux 内核为每个消息队列对象维护一个 msqid_ds,每个 msqid_ds 对应一个 id,消息以链表形式存储, 并且 msqid_ds 存放着这个链表的信息。

Linux进程间通信(消息队列)_第4张图片

消息队列的特点:

1.发出的消息以链表形式存储,相当于一个列表,进程可以根据 id 向对应的“列表”增加和获取消息。

2.进程接收数据时可以按照类型从队列中获取数据。

消息队列的使用步骤:

1. 创建 key;

2. msgget()通过 key 创建(或打开)消息队列对象 id; 3. 使用 msgsnd()/msgrcv()进行收发; 4. 通过 msgctl()删除 ipc 对象

通过 msgget()调用获取到 id 后即可使用消息队列访问 IPC 对象,消息队列常用 API 如下

Linux进程间通信(消息队列)_第5张图片

Linux进程间通信(消息队列)_第6张图片

Linux进程间通信(消息队列)_第7张图片

Linux进程间通信(消息队列)_第8张图片

 实验代码

msgsend.c  向消息队列里面写

#include 
#include 
#include 
#include 
#include 
struct msgbuf
{
    long mtype;
    char mtext[128];
};

int main(void)
{
    int msgid;
    key_t key;
    struct msgbuf msg;
    // 获取 key 值
    key = ftok("./a.c", 'a');
    // 获取到 id 后即可使用消息队列访问 IPC 对象
    msgid = msgget(key, 0666 | IPC_CREAT);
    if (msgid < 0)
    {
        printf("msgget is error\n");
        return -1;
    }
    printf("msgget is ok and msgid is %d \n", msgid);
    msg.mtype = 1;
    strncpy(msg.mtext, "hello", 5);
    // 发送数据
    msgsnd(msgid, &msg, strlen(msg.mtext), 0);
    return 0;
}

msgread.c 从消息队列里面读

#include 
#include 
#include 
#include 
#include 
struct msgbuf
{
    long mtype;
    char mtext[128];
};
int main(void)
{
    int msgid;
    key_t key;
    struct msgbuf msg;
    key = ftok("./a.c", 'a');
    // 获取到 id 后即可使用消息队列访问 IPC 对象
    msgid = msgget(key, 0666 | IPC_CREAT);
    if (msgid < 0)
    {
        printf("msgget is error\n");
        return -1;
    }
    printf("msgget is ok and msgid is %d \n", msgid);
    // 接收数据
    msgrcv(msgid, (void *)&msg, 128, 0, 0);
    printf("msg.mtype is %ld \n", msg.mtype);
    printf("msg.mtext is %s \n", msg.mtext);
    return 0;
}

在 Ubuntu 上开一个终端,编译运行如下图所示:

Linux进程间通信(消息队列)_第9张图片

 

你可能感兴趣的:(linux,ubuntu,c语言)