消息队列-C编程

问题描述 投票:0回答:1

目前,我非常困惑,因为不确定我是否正确理解自己的任务。我的理解是,我必须创建一个队列,每个队列中都包含一定数量的消息列表。我错了吗?我觉得我什么都没穿。我有一个错误的主意是什么队列吗?我应该创建一个队列吗?我到底应该怎么做?

    /* In their simplest form message queues are first-in-first-out (FIFO) queues, with newly sent message stored at the back and message delivery starts from the front of the queue.
     * In this task you are required to implement a very basic message queue,
       accessible just by the single program that uses it and where sent messages are not addressed to any specific recipient.
     * The end result takes the form of a new data type called MsgQs_t having the functions below.

     * Implement a simplified version of the data type and functions described above.
     * In this first step the MsgQs_t object and all associated message queues are stored on the heap.
     * However the maximum number of message queues that can be created, as well as the maximum size of each queue are fixed at compile-time.
     * Also, each individual message simply consists of a null-terminated string. */

    #include <stdio.h> //printf etc
#include <stdlib.h> //malloc calloc realloc free
#include <stdint.h>

#define MSG_BUF_LEN 10

/* number of message queues */
#define MSGQS_LEN 5

/* number of nodes in the message queue */
#define NMESSAGES 10

typedef struct _node {
    const char *message;
    struct _node *next;
} node_t;

typedef struct {
    char qName;
    node_t *front, *rear;
} msg_queue_t;


typedef struct {
    msg_queue_t **queues;
}MsgQs_t;


/* Returns a pointer to MsgQs_t structure and through which multiple message queues can be subsequently created.
   Each individual message queue is to be identified by a unique identifier. */
MsgQs_t * initializeMsgQs(){

    MsgQs_t *msg_queues;
    msg_queues = malloc(sizeof(MsgQs_t));

    if(msg_queues < 0)
        exit(EXIT_FAILURE);

    return(msg_queues);
}


/* Relinquishes all resources currently held by a MsgQs_t.
   The pointer to the MsgQs_t in question is set to NULL. */
MsgQs_t * unloadMsgQs(){
    MsgQs_t *msg_queues;
    msg_queues = NULL;

    return(msg_queues);
}

struct _node* newNode(const char *m){
    struct _node* temp = (struct _node*)malloc(sizeof(struct _node*));
    temp -> message = m;
    temp -> next = NULL;
    return temp;
}
/* Creates a new queue and which is assigned an identifier passed as argument.
   Specifying a currently assigned identifier returns an error.  */
msg_queue_t * createQ(){
    msg_queue_t* q = (msg_queue_t*)malloc(NMESSAGES);
    q -> front = q -> rear = NULL;
    return q;
}

// Enlists all currently created queues by their identifier and pending (undelivered) messages.
//listQs(){}

/* Deletes and relinquishes all resources held by the queue identified through its identifier.
   Returns an error if the queue identifier does not exist. */
msg_queue_t * deleteQ(){
    msg_queue_t* q = NULL;
    return q;
}


/* Sends a message to a single or all queues, depending on whether a queue identifier is specified.
   Returns an error if the queue identifier does not exist. */
void sendMessage(msg_queue_t* q, const char *m){
    //create a new LL node
    struct _node* temp = newNode(m);

            //if queue is empty, then new node is both front and rear
            if (q -> rear == NULL) {
                q -> front = q -> rear = temp;
                return;
            }

            //Add the new node at the end of queue and change rear
            q -> rear -> next = temp;
            q -> rear = temp;
}


/* As above but sends an entire array of messages at once. */
//sendMessageBatch(){}


/* Reads a specified number of messages from the front of the specified queue, or until the queue is empty.
   Each read message is removed from the queue. Returns an error if the queue identifier does not exist.  */
//receiveMessages(){}


/* Clears the specified queue, or all queues if no identifier is specified.
   Returns an error if the queue identifier does not exist.  */
//purgeQs(){}


/* Stores the identified queue to disk in a file called <queue_id>.dat.
   Returns an error if the queue identifier does not exist.  */
//persistQ(){}


/* Restores a queue previously stored by persistQ() back to memory as identified by its filename.
   The queue identifier is automatically taken from the filename.
   Returns an error if the filename does not exist or the queue id has been already taken. */
//restoreQ(){}


int main(){
    char choice, *msg, *q;

    printf("\n1 - Create a queue");
    printf("\n2 - List queues");
    printf("\n3 - Delete a queue");
    printf("\n4 - Send a message");
    printf("\n5 - Receive a message");
    printf("\n6 - Purge queue/s (If not specified, all queues will be cleared)");
    printf("\n7 - Persist a queue");
    printf("\n8 - Restore a queue");

    //createQ();

    while(1){
        printf("\nEnter choice: ");
        scanf(" %c", &choice);
        switch(choice){
            case '1':
                printf("Enter queue name");
                createQ(msg_queue_t -> qName);
            case '4':
                printf("Enter queue name:");
                scanf("%s", &q);
                printf("Enter message:");
                scanf("%s", &msg);
                sendMessage(q, msg);
                break;
            default:
                printf("Incorrrect, Re-try");
                break;
        }
    }

    return 0;
}
c struct queue message
1个回答
1
投票

不,您对队列是正确的想法。它告诉您MsgQs_t包含许多消息队列,每个消息队列包含一个队列和一个标识符(ID)。代码的结构如下所示

#define MSG_BUF_LEN (some_size)

/* number of message queues */
#define MSGQS_LEN   (some_size)

/* number of nodes in the message queue */
#define NMESSAGES   (some_size)

typedef struct _node {

    int8_t        message[MSG_BUF_LEN];

    struct _node *next;

} node_t;

typedef struct {

    int32_t id;

    node_t *first_message;

    node_t *last_message;

} msg_queue_t;


typedef struct {

    msg_queue_t **queues;

}MsgQs_t;



/* Returns a pointer to MsgQs_t structure and through which multiple message queues can be subsequently created.
   Each individual message queue is to be identified by a unique identifier. */
MsgQs_t * init_msgq(){

    MsgQs_t *msg_queues;

    msg_queues = malloc(sizeof(MsgQs_t));

    if(msg_queues < 0)
        exit(EXIT_FAILURE);

    return(msg_queues);
}

[您仍然必须实现其他功能,这些功能可帮助您初始化消息队列以及将消息添加到特定消息队列中-您必须将标识符和消息作为参数传递。

================================================ =========================

遍历您的代码存在主要问题,我建议您学习内存分配在C和指针中的工作方式。

/* Relinquishes all resources currently held by a MsgQs_t.
   The pointer to the MsgQs_t in question is set to NULL. */
MsgQs_t * unloadMsgQs(){
    MsgQs_t *msg_queues;
    msg_queues = NULL;

    return(msg_queues);
}

仅将指针设置为NULL将不会释放内存。您拥有的被称为内存泄漏,因为malloc仍占据该内存块,但您丢失了对其的引用。另外,不要忘记您还必须释放它的成员的内存,因为它本身不会递归地进行。

struct _node* newNode(const char *m){
    struct _node* temp = (struct _node*)malloc(sizeof(struct _node*));
    temp -> message = m;
    temp -> next = NULL;
    return temp;
}

sizeof(struct _node*)将返回指针的大小,而不是结构本身的大小。请注意sizeof(struct _node)sizeof(struct _node*)有什么区别,这很重要。

其余代码将无法正常运行。由于这不是代码审查社区,因此我将在这里停止并建议您先熟悉指针及其工作原理,然后再继续进行操作。

© www.soinside.com 2019 - 2024. All rights reserved.