IPC MSG队列如何识别发送的每条消息的消息类型?

4nkexdtk  于 2022-12-03  发布在  其他
关注(0)|答案(1)|浏览(86)

我刚刚了解了MSG队列,我尝试用公共键编写两个进程,其中一个进程发送消息,另一个进程读取消息,然后删除队列。

以下是我的控制台结果:

发送的消息:MSG_6发送的消息:MSG_2发送的消息:MSG_8发送的消息:MSG_9发送的消息:MSG_8发送的消息:MSG_3发送的消息:MSG_6发送的消息:MSG_6发送的消息:MSG_2发送的消息:MSG_5接收类型:5、MSG_6接收类型:5、MSG_2接收类型:5、MSG_8接收类型:5、MSG_9接收类型:5、MSG_8接收类型:5、MSG_3接收类型:5、MSG_6接收类型:5、MSG_6接收类型:5、MSG_2接收类型:5,MSG_5现在将在3秒内删除QEUE
我希望mtype和每个发送的MSG都一样。但是,正如你所看到的,接收器进程只打印最后一个MSG类型。如果我能得到每个MSG类型,我就可以用某种方式对它们进行排序。

IPC_COMMON.h其中发送方和接收方都包含此头文件。

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

#define TEST_ERROR    if (errno) {fprintf(stderr, \
                      "%s:%d: PID=%5d: Error %d (%s)\n", \
                      __FILE__,         \
                      __LINE__,         \
                      getpid(),         \
                      errno,            \
                      strerror(errno));}
#define MSG_LEN 120

struct msgbuf {
    long mtype;
    char mtext[MSG_LEN];
};

#define MY_KEY 0x123456
#define MSGTYPE_RM  7

发送方.c

#include "testCommon.h"
#include <time.h>

int main() {
    int id_q;
    struct msgbuf my_msg;
    int typeArr[10];
    int i;
    
    id_q = msgget(MY_KEY, IPC_CREAT | 0600);
    TEST_ERROR;
    
    srand(time(NULL));
        
    for(i = 0; i < 10; i++) {
        typeArr[i] = rand() % 10;
        my_msg.mtype = typeArr[i];
        printf("Printing types %d\n", typeArr[i]);      
    }
    
    for(i = 0; i < 10; i++) {
        switch(typeArr[i]) {
        case 0:
            strcpy(my_msg.mtext , "MSG_0");
            msgsnd(id_q, &my_msg, MSG_LEN, 0);
            printf("MSG sent: %s\n", my_msg.mtext);
            break;
        case 1:
            strcpy(my_msg.mtext , "MSG_1");
            msgsnd(id_q, &my_msg, MSG_LEN, 0);
            printf("MSG sent: %s\n", my_msg.mtext);
            break;
        case 2:
            strcpy(my_msg.mtext , "MSG_2");
            msgsnd(id_q, &my_msg, MSG_LEN, 0);
            printf("MSG sent: %s\n", my_msg.mtext);
            break;
        case 3:
            strcpy(my_msg.mtext , "MSG_3");
            msgsnd(id_q, &my_msg, MSG_LEN, 0);
            printf("MSG sent: %s\n", my_msg.mtext);
            break;
        case 4:
            strcpy(my_msg.mtext , "MSG_4");
            msgsnd(id_q, &my_msg, MSG_LEN, 0);
            printf("MSG sent: %s\n", my_msg.mtext);
            break;
        case 5:
            strcpy(my_msg.mtext , "MSG_5");
            msgsnd(id_q, &my_msg, MSG_LEN, 0);
            printf("MSG sent: %s\n", my_msg.mtext);
            break;
        case 6:
            strcpy(my_msg.mtext , "MSG_6");
            msgsnd(id_q, &my_msg, MSG_LEN, 0);
            printf("MSG sent: %s\n", my_msg.mtext);
            break;
        case 7:
            strcpy(my_msg.mtext , "MSG_7");
            msgsnd(id_q, &my_msg, MSG_LEN, 0);
            printf("MSG sent: %s\n", my_msg.mtext);
            break;
        case 8:
            strcpy(my_msg.mtext , "MSG_8");
            msgsnd(id_q, &my_msg, MSG_LEN, 0);
            printf("MSG sent: %s\n", my_msg.mtext);
            break;
        case 9:
            strcpy(my_msg.mtext , "MSG_9");
            msgsnd(id_q, &my_msg, MSG_LEN, 0);
            printf("MSG sent: %s\n", my_msg.mtext);
            break;
        default:
            fprintf(stderr, "Error occurred\n.");
            TEST_ERROR;
        }
    }
    return 0;
}

接收方.c

#include "testCommon.h"

int main() {
    int q_id, num_bytes, i;
    struct msgbuf my_msg;
    num_bytes = 0;
    q_id = msgget(MY_KEY, IPC_CREAT | 0600);
    TEST_ERROR;
    
    while (1) {
        /* now receiving the message */
            for(i = 0; i < 10; i++) {
            num_bytes += msgrcv(q_id, &my_msg, MSG_LEN, 0, 0);
            printf("Recieved type: %ld, %s \n", my_msg.mtype, my_msg.mtext);
            }   
            if(num_bytes >= 0)
            break;  
    }
    printf("Now removing the QEUE in 3 seconds\n");
    sleep(3);
    msgctl(q_id, IPC_RMID, NULL);       
}
hwamh0ep

hwamh0ep1#

我希望mtype与发送的每个MSG相同。
您的代码中有一些问题,我在对这个问题的评论中已经提到过了。但 * 主要 * 问题似乎是在向队列发送任何消息之前最后一次设置my_msg.mtype。每次都设置mtext数据,但没有设置mtype。因此,我希望所有的消息都是由typeArr[9]指定的消息类型,因为这是您设置的最后一个mtype值。
您可以尝试使用以下代码来代替发送方的两个for循环:

for (i = 0; i < 10; i++) {
        my_msg.mtype = 1 + rand() % 9;
        sprintf(my_msg.mtext, "MSG_%ld", my_msg.mtype);
        ssize_t result = msgsnd(id_q, &my_msg, MSG_LEN, 0);
        if (result == -1) {
            // handle error ...
        } else {
            printf("MSG type %ld sent: %s\n", my_msg.mtype, my_msg.mtext);
        }
    }

相关问题