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

文章介绍了Linux中的IPC机制,特别是消息队列的使用。通过`ipcs`和`ipcrm`命令管理IPC对象,应用层使用IPC通信通常包括获取key、调用IPCget以及通过ID操作对象。消息队列以链表形式存储数据,支持按类型获取。示例代码展示了如何使用`msgget`,`msgsnd`和`msgrcv`进行消息的发送和接收。
摘要由CSDN通过智能技术生成

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

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

 

 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,用到的函数如下:

 下面介绍消息队列:

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

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

消息队列的特点:

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

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

消息队列的使用步骤:

1. 创建 key;

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

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

 实验代码

msgsend.c  向消息队列里面写

#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <string.h>
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 <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <string.h>
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 上开一个终端,编译运行如下图所示:

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值