← 返回首页
Linux高级程序设计(六十一)
发表时间:2021-12-16 23:22:23
发送消息

1.消息格式

typedef struct _msg  
{  
    long mtype;      // 消息类型  
    char mtext[100]; // 消息正文  
    //...         // 消息的正文可以有多个成员  
}MSG;  

消息类型必须是长整型的,而且必须是结构体类型的第一个成员,类型下面是消息正文,正文可以有多个成员(正文成员可以是任意数据类型的)。至于这个结构体类型叫什么名字,里面成员叫什么名字,自行定义,没有明确规定。

2.发送消息

#include <sys/msg.h>

int msgsnd(  int msqid, const void *msgp, size_t msgsz, int msgflg);

功能: 将新消息添加到消息队列。

参数: - msqid: 消息队列的标识符。 - msgp: 待发送消息结构体的地址。 - msgsz: 消息正文的字节数。 - msgflg:函数的控制属性,其取值如下: 0:msgsnd() 调用阻塞直到条件满足为止。 IPC_NOWAIT: 若消息没有立即发送则调用该函数的进程会立即返回。

返回值: 成功:0 失败:-1

3.实例

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

#define N 128
typedef struct _msg  
{  
    long mtype;      // 消息类型  
    char mtext[N]; // 消息正文  
    //...         // 消息的正文可以有多个成员  
}MSG; 

//定义消息体长度
#define MSG_SIZE (sizeof(MSG)-sizeof(long))

int main(int argc, char *argv[])
{
    key_t key;
    int msgqid;

    key = ftok(".", 2021); // key 值
    if (key == -1)
    {
        perror("error to ftok:");
        exit(1);
    }

    // 创建消息队列
    msgqid = msgget(key, IPC_CREAT | 0666);
    if (msgqid == -1)
    {
        perror("error to create message queue:");
        exit(1);
    }

    printf("key=%#x\n",key);
    printf("msgqid=%d\n",msgqid);
    system("ipcs -q");

    MSG msg1 = {1,"hello,world!"};
    MSG msg2 = {2,"hello,ketty!"};
    MSG msg3 = {3,"hello,linux!"};
    MSG msg4 = {4,"hello,java!"};

    if(msgsnd(msgqid,&msg1,MSG_SIZE,0)==-1){
        perror("error to send msg:");
        exit(1);
    }

    if(msgsnd(msgqid,&msg2,MSG_SIZE,0)==-1){
        perror("error to send msg:");
        exit(1);
    }

    if(msgsnd(msgqid,&msg3,MSG_SIZE,0)==-1){
        perror("error to send msg:");
        exit(1);
    }

    if(msgsnd(msgqid,&msg4,MSG_SIZE,0)==-1){
        perror("error to send msg:");
        exit(1);
    }

    system("ipcs -q");

    return 0;
}

运行结果:

[root@iz2zefozq9h39txdb8s7npz shelldemo]# ./a.out
key=0xe5010131
msgqid=65536

------ Message Queues --------
key        msqid      owner      perms      used-bytes   messages    
0xe5010131 65536      root       666        0            0           


------ Message Queues --------
key        msqid      owner      perms      used-bytes   messages    
0xe5010131 65536      root       666        512          4      

再执行一次结果为:

[root@iz2zefozq9h39txdb8s7npz shelldemo]# ./a.out
key=0xe5010131
msgqid=65536

------ Message Queues --------
key        msqid      owner      perms      used-bytes   messages    
0xe5010131 65536      root       666        512          4           


------ Message Queues --------
key        msqid      owner      perms      used-bytes   messages    
0xe5010131 65536      root       666        1024         8     

说明原先的消息队列里的数据不会被清除。