进程间通讯--消息队列

         进程间通讯--消息队列

 

 

1.  创建消息队列

       #include <sys/types.h>
       #include <sys/ipc.h>
       #include <sys/msg.h>
       int msgget(key_t key, int msgflg);

                   成功返回队列ID,失败返回-1

参数

说明

key

创建/打开队列key,ftok产生,可以直接给常量

msgflg

创建/打开方式IPC_CREATIPC_EXCLIPC_NOWAIT

            通常是msgflg =IPC_CREAT| IPC_EXCL|0666,意思是若不存在key值的队列则创建,否则如果存在则打开队列,0666意思与一般文件权限一样,XXX-本用户,同组用户,其他用户的读写执行的权限。

       # include <sys/types.h>
       # include <sys/ipc.h>
       key_t ftok(const char *pathname, int proj_id);

//获取pathname相对应的一个键值, pathname必须是存在并且可读取的文件,proj_id表示序号,用来区别同时的存在文件。成功返回key值,失败返回-1

          

2.  队列读写

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

a)         读取数据――阻塞读取消息队列,直到解除阻塞。

ssize_t msgrcv(int msqid, struct msgbuf *msgp, size_t msgsz, long msgtyp, int msgflg);

参数

说明

msqid

已打开的消息队列id

msgp

接收存放的消息队列缓存结构

msgsz

消息数据长度

msgtyp

消息类型。=0 读取队列中第一个数据。

msgflg

读取标志通常使用IPC_NOWAIT:即没有满足条件的消息,立即返回,此时,错误代码errno=ENOMSG

IPC_EXCEPT:与msgtyp>0配合使用,返回队列中第一个类型不为msgtyp的消息

MSG_NOERROR:截断超长数据

缓冲内容结构如下:

struct msgbuf {
long mtype;    /* 消息类型 must be > 0 */
char mtext[1]; /* 消息数据 这里只是一个数组的首地址,并非是只有一个字符 */
            };

msgrcv()解除阻塞的条件三个条件:

1.  消息队列中有了满足条件的消息(或使用了);

2.  msqid代表的消息队列被删除;

3.  调用msgrcv()的进程被信号中断;

a)         发送数据

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

参数

说明

msqid

已打开的消息队列id

ght: windowtext 1pt solid; padding-right: 5.4pt; border-top: #ece9d8; padding-left: 5.4pt; padding-bottom: 0cm; border-left: windowtext 1pt solid; width: 99pt; padding-top: 0cm; border-bottom: windowtext 1pt solid; background-color: transparent;" width="132" valign="top">

msgp

发送存放的消息队列缓存结构

msgsz

消息数据长度

msgflg

消息类型。=0 读取队列中第一个数据。

 

 

 

3.  消息队列控制

       #include <sys/types.h>
       #include <sys/ipc.h>
       #include <sys/msg.h>    
       int msgctl(int msqid, int cmd, struct msqid_ds *buf);

          成功返回0,失败返回-1

参数

说明

msqid

已打开的消息队列id

cmd

控制类型选项

IPC_STAT:取得队列状态

IPC_SET:设置队列属性

IPC_RMID:删除消息队列

buf

存放队列的属性结构

 

       队列属性如下:

struct msqid_ds
{
  struct ipc_perm msg_perm; /* structure describing operation permission */
  __time_t msg_stime; /*最后一次发送消息的时间 */
  unsigned long int __unused1; /*保留*/
  __time_t msg_rtime; /* 最后一次接收数据时间 */
  unsigned long int __unused2;     /*保留*/
  __time_t msg_ctime; /* 最后修改时间 */
  unsigned long int __unused3; /*保留*/
  unsigned long int __msg_cbytes; /* 当前队列字节数 */
  msgqnum_t msg_qnum; /* 当前队列的消息数 */
  msglen_t msg_qbytes; /* 队列中容量 */
  __pid_t msg_lspid; /* 最后发送消息的进程号 */
  __pid_t msg_lrpid; /* 最后接收队列的进程号*/
  unsigned long int __unused4; /*保留*/
  unsigned long int __unused5; /*保留*/
};

4.例子:

#include <sys/types.h>
#include <sys/msg.h>
#include <unistd.h>
#define msgkey 0x11000001
struct msg_buf
    {
        int mtype;
        char data[255];
    };
 
int main()
{
        key_t key;
        int msgid;
        int ret;
        struct msg_buf msgbuf;
 
        key=ftok("/tmp/1",'a');
        printf("key =[%x]/n",key);
        //msgid=msgget(key,IPC_CREAT|IPC_EXCL|0666); /*通过文件对应*/
        msgid=msgget(msgkey,IPC_CREAT|IPC_EXCL|0666);/*或者取常量*/
        if(msgid==-1)
        {
                printf("create error/n");
                return -1;
        }
 
        msgbuf.mtype = getpid();
        strcpy(msgbuf.data,"test haha");
        ret=msgsnd(msgid,&msgbuf,sizeof(msgbuf.data),IPC_NOWAIT);
        if(ret==-1)
        {
                printf("send message err/n");
                return -1;
        }
 
        memset(&msgbuf,0,sizeof(msgbuf));
        ret=msgrcv(msgid,&msgbuf,sizeof(msgbuf.data),getpid(),IPC_NOWAIT);
        if(ret==-1)
        {
                printf("recv message err/n");
                return -1;
        }
        printf("recv msg =[%s]/n",msgbuf.data);
 
        ret=msgctl(msgid,IPC_RMID,NULL);//删除消息队列

        if(ret==-1)
        {
                printf("del msg err/n");
                return -1;
        }
 
}

 

  进程间通讯信息查看

         ipcs -q  --查看消息队列信息,具体 man ipcs可以看到更多的内容

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在Linux下,QT可以使用mqueue消息队列实现进程通信。为了使用消息队列,需要包含头文件#include <mqueue.h>,并在pro文件中添加编译选项LIBS = -lrt。消息队列具有以下特征:可以设置最大消息个数和每个消息的最大字节数,可以向消息队列中写入多条消息,而其他进程读取一条消息后,消息队列就会删除这条消息。 要发送消息消息队列中,可以使用mq_send函数。该函数的原型是int mq_send(mqd_t mqdes, const char *ptr, size_t len, unsigned int prio)。其中,mqdes是打开消息队列时返回的消息队列描述符,ptr是指向要发送的消息的指针,len是消息的长度,prio是消息的优先级。 在应用中使用消息队列进行进程通信,可以发现消息队列具有强大的功能。它可以方便地管理线程,实现互斥量和条件变量等功能。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [Qt实现IPC进程通信-mqueue消息队列](https://blog.csdn.net/weixin_40355471/article/details/113178838)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *3* [进程通信之深入消息队列的详解](https://download.csdn.net/download/weixin_38517212/14872197)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值