5. Operating system - inter-process communication (3) (system V-IPC: message queue)

Table of contents

1. Disadvantages of the pipeline

2. Message queue

3. API of message queue

  (1) Get the ID of the message queue (like a file descriptor) (msgget)

  (2) Send and receive messages (msgrcv)

    (3) Get and set the properties of the message queue (msgctl)

4. How to use the message queue

(1) sender

(2) Receiver

1. Disadvantages of the pipeline

(1) A "specified" data cannot be read, because the data is not marked, so it can only be read one by one in order

(2) The mutual communication between multiple pairs of processes must be handled separately with multiple pairs of pipelines

2. Message queue

(1) A special pipeline with data identification, and each piece of written data becomes a message with identification.

(2) The process that reads the message can read it correctly as long as the identifier is specified without being disturbed by other messages

(3) Judging from the running effect, a message queue with a logo is like multiple concurrent pipelines

3. API of message queue

(1) Get the ID of the message queue (like a file descriptor) (msgget)

 (2) Send and receive messages (msgrcv)

a. When sending a message, the message must be organized into the following form

struct msgbuf
{
    long mtype; // 消息的标识
    char mtext[1]; // 消息的正文 可以是任何类型数据
};

The message to be sent must start with a long data as the identifier of the message, and the following data is not required.

b. The identifier of the message can be any long integer value, but cannot be 0L.

c. The parameter msgsz is the size of the text in the message, excluding the message ID.

(3) Get and set the properties of the message queue (msgctl)

4. How to use the message queue

(1) sender

A) Get the ID of the message queue

B) Put the data into a special structure with an identifier and send it to the message queue.

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

struct msgbuf
{
    long mtype; // 【重点】消息的标识
    int num ; // 消息的正文 可以是任何类型数据
};

int main(int argc, char const *argv[])
{
    
    // 获得KEY值
    key_t key =  ftok("./",  1 );
    printf("key:%d\n" , key );
    
    // 获得消息队列的ID 
    int ID = msgget( key , IPC_CREAT | 0644 );
    printf("消息队列ID 为:%d \n " , ID );

    // 配置消息
    struct msgbuf msg = {
        .mtype = 'X',  // 设置消息数据的类型(标识)
        .num = 1024   // 实际发送的信息
    };

    // 发送消息
    msgsnd(ID , &msg , sizeof(msg.num), MSG_NOERROR);

    // 标记删除
     msgctl(ID , IPC_RMID , NULL );

    return 0;
}

(2) Receiver

A) Get the ID of the message queue

B) Read out the message with the specified ID.

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

struct msgbuf
{
    long mtype; // 【重点】消息的标识
    int num ; // 消息的正文 可以是任何类型数据
};

int main(int argc, char const *argv[])
{
    
    // 获得KEY值
    key_t key =  ftok("./",  1 );
    printf("key:%d\n" , key );
    
    // 获得消息队列的ID 
    int ID = msgget( key , IPC_CREAT | 0644 );
    printf("消息队列ID 为:%d \n " , ID );

    // 配置消息
    struct msgbuf msg = {0};

    // 接收消息
    // int  msg  ; 
    int ret_val = msgrcv( ID , &msg, sizeof(msg.num), 'X', MSG_NOERROR );
    printf("ret:%d msg:%d\n" , ret_val, msg.num );


    // 标记删除
    msgctl(ID , IPC_RMID , NULL );
    
    return 0;
}

Guess you like

Origin blog.csdn.net/weixin_45981798/article/details/129780424