linux消息队列

目录

一、查看ipc对象:

二、消息队列的概念

三、消息队列相关函数 

1、获得key值 

2、获取或创建消息队列

3、发送消息 

4、接收消息 

5、获取或设置消息队列对象的信息


system V IPC对象是内核中实际存在的对象,用于进程间通信
可以通过shell命令来管理这些对象:


一、查看ipc对象:

yutou@ubuntu:~/2206/process/homework/day03_hw$ ipcs

--------- 消息队列 -----------   
键        msqid      拥有者  权限     已用字节数 消息

------------ 共享内存段 --------------
键        shmid      拥有者  权限     字节     连接数  状态
0x00000000 6          farsight   600        67108864   2          目标
0x00000000 11         farsight   600        524288     2          目标
0x00000000 12         farsight   600        524288     2          目标
0x00000000 13         farsight   600        524288     2          目标

--------- 信号量数组 -----------
键        semid      拥有者  权限     nsems



分别查看不同类型的ipc对象
yutou@ubuntu:~/2206/process/homework/day03_hw$ ipcs -q      //只查看消息队列

--------- 消息队列 -----------
键        msqid      拥有者  权限     已用字节数 消息


yutou@ubuntu:~/2206/process/homework/day03_hw$ ipcs -m        //只查看共享内存

------------ 共享内存段 --------------
键        shmid      拥有者  权限     字节     连接数  状态
0x00000000 6          farsight   600        67108864   2          目标
0x00000000 11         farsight   600        524288     2          目标
0x00000000 12         farsight   600        524288     2          目标
0x00000000 13         farsight   600        524288     2          目标


yutou@ubuntu:~/2206/process/homework/day03_hw$ ipcs -s        //只查看信号量

--------- 信号量数组 -----------
键        semid      拥有者  权限     nsems


删除ipc对象:
ipcrm -q  id
ipcrm -m  id
ipcrm -s  id


这些systemV IPC对象操作思路是一致的,如下: 

        获取key                                   打开或获取ipc对象  
    ftok()-->key                             | ---> msgget()          |    msgrcv() ,msgsnd() msgctl()
    IPC_PRIVATE-->key               | ---> shmget()         |  shmat() , shmdt()  shmctl()
                                                      ---> semget()         |  semop(), semctl()

二、消息队列的概念

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

三、消息队列相关函数 

1、获得key值 

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

       key_t ftok(const char *pathname, int proj_id);
       //参数1 --- 工程目录
       //参数2 --- 项目编号
       //返回值 ----成功:key,失败:-1

2、获取或创建消息队列

        #include <sys/types.h>
       #include <sys/ipc.h>
       #include <sys/msg.h>       int msgget(key_t key, int msgflg);
       //参数1 ----- key:  通过ftok()获取,或 IPC_PRIVATE:由系统分配
       //参数2 ----- 权限: IPC_CREAT | 0666 
       //返回值 ---- 成功:消息队列的ID ,失败:-1 
       
    例如: 

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

        #define perr(str) ({perror(str);exit(1);})

        int main(void)
        {
            key_t key;
            int msg_id;
            //先获取key
            if((key=ftok("./",0xa)) < 0)
                perr("ftok");

            //创建或获取消息队列的ID
            if((msg_id = msgget(key,IPC_CREAT|0666)) < 0)
                perr("msgget");

            return 0;
        }

3、发送消息 

int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
        //参数1 ---- 消息队列ID 
        //参数2 ---- 结构体指针,类型为:struct msgbuf*  ,该结构体需要自定义,如下:
                     struct msgbuf {
                           long mtype;       /* message type, must be > 0 */
                           char mtext[1];    /* message data */
                       };
        //参数3 ---- 表示消息正文的大小,也就是mtext的中数据的长度
       //参数4 ----- 标签:0 ---如果不能立即发送,则阻塞,IPC_NOWAIT---如果不能立即发送则直接返回
      //返回值 ---- 成功:0,失败:-1 

4、接收消息 

ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg);    
        //参数1 ----- 消息队列ID
        //参数2 ----- 结构体指针,类型为:struct msgbuf*  ,该结构体需要自定义,如下:
                     struct msgbuf {
                           long mtype;       /* message type, must be > 0 */
                           char mtext[1];    /* message data */
                       };
        //参数3 ---- 表示消息正文的大小,也就是mtext的长度
        //参数4 ---- msgtyp: 
                        msgtyp > 0  ----要接收的消息的类型
                        msgtyp = 0  ----按消息的顺序接收不同类型消息
                        msgtyp < 0  ----接收消息类型不大于msgtyp绝对值的最小的消息
        //参数5 ---- 标签:0 ---如果不能立即接收,则阻塞,IPC_NOWAIT---如果不能立即接收则直接返回
        //返回值 ---- 成功:接收到的字节数,失败:-1
        
        例如: 

 #include "msg.h"                                            
                                                           
 int main(void)                                              
 {                                                          
     key_t key;                                              
     int msg_id;                                           
     struct msgbuf buf;                                     
                                                             
     //先获取key                                             
     if((key=ftok("./",0xa)) < 0)                            
         perr("ftok");                                      
                                                           
     //创建或获取消息队列的ID                                
    if((msg_id = msgget(key,IPC_CREAT|0666)) < 0)           
         perror("msgget");                                      
                                                            
     //向消息队列中发送消息                               
     while(1){                                             
         memset(&buf,0,sizeof(buf));                        
         printf("请输入消息类型:");                       
         scanf("%ld",&buf.mtype);                              
         while(getchar() != '\n');                              
         printf("请输入消息:");                                     
         fgets(buf.mtext,SIZE,stdin);                            
         buf.mtext[strlen(buf.mtext)-1] = '\0';              
         if(msgsnd(msg_id,&buf,strlen(buf.mtext),0) <0)    
             perr("msgsnd");                                
     }                                                       
                                                            
         return 0;                                          
}                                                        


 

#include "msg.h"
int main(void)
{
     key_t key;
     int msg_id;
     struct msgbuf buf;
     //先获取key
     if((key=ftok("./",0xa)) < 0)
        perr("ftok");

     //创建或获取消息队列的ID
     if((msg_id = msgget(key,IPC_CREAT|0666)) < 0)
         perr("msgget");
    //向消息队列中发送消息
     while(1){
         memset(&buf,0,sizeof(buf));
         printf("请输入消息类型:");
         scanf("%ld",&buf.mtype);
         if(msgrcv(msg_id,&buf,SIZE,buf.mtype,0) <0)
             perr("msgrcv");
         printf("%s\n",buf.mtext);
     }
     return 0;
 }

5、获取或设置消息队列对象的信息

int msgctl(int msqid, int cmd, struct msqid_ds *buf);
        //参数1 ----- 消息队列ID
        //参数2 ----- 命令: 
                         IPC_STAT  -----获取消息队列的属性,通过参数三返回
                         IPC_SET   ----- 设置消息队列的属性
                         IPC_RMID  ----- 删除消息队列
        //参数3 ----- 结构体struct msqid_ds的指针 
                          struct msqid_ds {
                               struct ipc_perm msg_perm;     /* Ownership and permissions */
                               time_t          msg_stime;    /* Time of last msgsnd(2) */
                               time_t          msg_rtime;    /* Time of last msgrcv(2) */
                               time_t          msg_ctime;    /* Time of last change */
                               unsigned long   __msg_cbytes; /* Current number of bytes in
                                                                queue (nonstandard) */
                               msgqnum_t       msg_qnum;     /* Current number of messages
                                                                in queue */
                               msglen_t        msg_qbytes;   /* Maximum number of bytes
                                                                allowed in queue */
                               pid_t           msg_lspid;    /* PID of last msgsnd(2) */
                               pid_t           msg_lrpid;    /* PID of last msgrcv(2) */
                           };
        例如: 

        int main(int argc,char **argv)
        {
            int msg_id;
            if(argc != 2){
                fprintf(stderr,"Usage: %s <msgid>\n",argv[0]);
                exit(1);
            }

            msg_id = atoi(argv[1]);
            if(msgctl(msg_id,IPC_RMID,NULL) < 0)
                perr("msgctl");

            return 0;
        }

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值