进程间通信方式(三)-- IPC对象(消息队列、共享内存、信号灯集)

本文介绍了Linux系统中的三种IPC(进程间通信)对象:消息队列、共享内存和信号灯集。详细讲解了它们的概念、相关函数及其使用示例。消息队列允许按类型发送/接收消息,共享内存提供高效的数据交换,而信号灯集用于进程间的同步控制。
摘要由CSDN通过智能技术生成

1. IPC对象

IPC对象主要指三种进程间通信机制:消息队列、共享内存、信号灯集

优点:创建IPC对象后,在当前系统中所有进程都是可见的。


2. 查看IPC对象命令

使用ipcs查看当前ipc对象

ipcs 查看所有的ipc对象
       -q  查看消息队列
       -m 查看共享内存
        -s  查看信号量
ipcrm 删除ipc对象
          ipcrm –q msqid 删除指定的消息队列

3. 消息队列

3.1 概念

  • 消息队列是IPC对象的一种
  • 消息队列由消息队列ID唯一标识
  • 消息队列就是一个消息的列表。用户可以在消息队列中添加消息读取消息等。
  • 消息队列可以按照类型来发送/接收消息

3.2 相关函数

3.2.1 msgget() 创建或者打开消息队列

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>

int msgget(key_t key, int msgflg);
功能:
	创建或者打开一个消息队列,得到消息队列id
参数:
     key:键值,唯一的键值确定唯一的消息队列
         如何设置键值:
             自己直接定义一个键值
             使用ftok函数获取键值
    msgflg:标志位
        一般设置为 IPC_CREAT | 0777
返回值:
    成功:消息队列id
    失败:-1


3.2.2 ftok() 获取键值

#include <sys/types.h>
#include <sys/ipc.h>
key_t ftok(const char *pathname, int proj_id);
功能:
	获取键值
参数:
    pathname:路径名
    proj_id:自定义的值,只取前八位
返回值:
    成功:键值
    失败:-1

3.2.3 msgctl() 控制消息队列

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
int msgctl(int msqid, int cmd, struct msqid_ds *buf);
功能:
	控制一个消息队列
参数:
    msqid:消息队列id
    cmd:具体控制
        IPC_STAT 获取消息队列属性信息
        IPC_SET 设置消息队列属性信息
        IPC_RMID 删除一个消息队列
    msqid_ds:消息队列属性结构体
返回值:
    成功:0
    失败:-1

3.2.4 msgsnd() 向消息队列写信息

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
功能:向一个消息队列中写入数据
参数:
    msqid:消息队列id
    msgp:要写入的数据,需要自己定义一个结构体
        struct msg_buf{
   
       		 //消息类型,必须有且类型也不能变
      		 // 用于读取数据时,可以指定消息的类型来读取
              long type; 
             //消息正文具体要写入的数据,大小自己定义,类型也可以自定义             
              char mtext[32]; 
        };
    msgsz:消息正文的大小,就是mtext的大小,一定不是第二个参数的大小
    msgflg:标志位
        0   阻塞
        IPC_NOWAIT  非阻塞
返回值:
    成功:0
    失败:-1

3.2.5 msgrcv() 从消息队列读

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, 
                long msgtyp, int msgflg);
功能:从消息队列中读取数据
参数:
    msqid:消息队列id
    msgp:保存读取的数据
    msgsz:消息正文大小
    msgtyp:消息类型
        0    按照顺序读取一个消息
        >0   按照顺序读取第一个消息类型为当前参数的消息
        <0   按照顺序读取第一个消息类型小于等于这个参数的绝对值的类型的消息
    msgflg:标志位
        0   阻塞
        IPC_NOWAIT  非阻塞
返回值:
    成功:接收到的数据的大小
    失败:-1

3.3 消息队列 示例

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <unistd.h>

typedef struct{
   
    long type;
    int id;
    char name[32];
    int score;
}MSG;

#define DATASIZE (sizeof(MSG) - sizeof(long))

int main(int argc, char const *argv[])
{
   
    //使用ftok函数获取键值
    key_t key;
    if((key = ftok(".", 1000)) == -1)
    {
   
        perror("ftok error");
        exit(1);
    }
    //ftok函数获取的健值就是
    //这个函数的第二个参数的后8位 ↓
    //和 第一个参数对应文件的设备号的后8位 ↓
    //以及这个文件inode号的后16位 ↓
    //共同组成键值
    
    // printf("key = %#x\n", key);
    // struct stat mystat;
    // stat(".", &mystat);
    // printf("dev_num = %x\n", mystat.st_dev);
    // printf("inode = %x\n", mystat.st_ino);
    // printf("1000 = %#x\n", 1000);
  
    //创建一个消息队列
    int msgid;
    if((msgid = msgget(key, IPC_CREAT | 0777)) == -1)
    {
   
        perror("msgget error");
        exit(1);
    }
    
    puts("--------------------------------------------")
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值