如何在基于 Linux 的系统上的 ac 程序中使用 mqueue?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3056307/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-03 20:08:12  来源:igfitidea点击:

How do I use mqueue in a c program on a Linux based system?

clinuxipcmqueue

提问by Johan

How do I use mqueue (message queue) in a c program on a Linux based system?

如何在基于 Linux 的系统上的 ac 程序中使用 mqueue(消息队列)?

I'm looking for some good code examples that can show how this is done in a correct and proper way, maybe a howto.

我正在寻找一些好的代码示例,它们可以展示如何以正确和正确的方式完成这项工作,也许是一个 howto。

采纳答案by the_void

The following is a simple example of a server that receives messages from clients until it receives an "exit" message telling it to stop.

下面是一个简单的服务器示例,它从客户端接收消息,直到它收到一个“退出”消息告诉它停止。

The code for the server:

服务器的代码:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <errno.h>
#include <mqueue.h>

#include "common.h"

int main(int argc, char **argv)
{
    mqd_t mq;
    struct mq_attr attr;
    char buffer[MAX_SIZE + 1];
    int must_stop = 0;

    /* initialize the queue attributes */
    attr.mq_flags = 0;
    attr.mq_maxmsg = 10;
    attr.mq_msgsize = MAX_SIZE;
    attr.mq_curmsgs = 0;

    /* create the message queue */
    mq = mq_open(QUEUE_NAME, O_CREAT | O_RDONLY, 0644, &attr);
    CHECK((mqd_t)-1 != mq);

    do {
        ssize_t bytes_read;

        /* receive the message */
        bytes_read = mq_receive(mq, buffer, MAX_SIZE, NULL);
        CHECK(bytes_read >= 0);

        buffer[bytes_read] = '
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <mqueue.h>

#include "common.h"


int main(int argc, char **argv)
{
    mqd_t mq;
    char buffer[MAX_SIZE];

    /* open the mail queue */
    mq = mq_open(QUEUE_NAME, O_WRONLY);
    CHECK((mqd_t)-1 != mq);


    printf("Send to server (enter \"exit\" to stop it):\n");

    do {
        printf("> ");
        fflush(stdout);

        memset(buffer, 0, MAX_SIZE);
        fgets(buffer, MAX_SIZE, stdin);

        /* send the message */
        CHECK(0 <= mq_send(mq, buffer, MAX_SIZE, 0));

    } while (strncmp(buffer, MSG_STOP, strlen(MSG_STOP)));

    /* cleanup */
    CHECK((mqd_t)-1 != mq_close(mq));

    return 0;
}
'; if (! strncmp(buffer, MSG_STOP, strlen(MSG_STOP))) { must_stop = 1; } else { printf("Received: %s\n", buffer); } } while (!must_stop); /* cleanup */ CHECK((mqd_t)-1 != mq_close(mq)); CHECK((mqd_t)-1 != mq_unlink(QUEUE_NAME)); return 0; }

The code for the client:

客户端的代码:

#ifndef COMMON_H_
#define COMMON_H_

#define QUEUE_NAME  "/test_queue"
#define MAX_SIZE    1024
#define MSG_STOP    "exit"

#define CHECK(x) \
    do { \
        if (!(x)) { \
            fprintf(stderr, "%s:%d: ", __func__, __LINE__); \
            perror(#x); \
            exit(-1); \
        } \
    } while (0) \


#endif /* #ifndef COMMON_H_ */

The commonheader:

常见的头:

gcc -o server server.c -lrt
gcc -o client client.c -lrt

Compiling:

编译

#include <stdio.h>
#include <fcntl.h>
#include <mqueue.h>

int main(int argc, char *argv[])
{
    mqd_t mq;               // message queue
    struct mq_attr ma;      // message queue attributes
    int status = 0;
    int a = 5;
    int b = 0;

    printf("a = %d, b = %d\n", a, b);

    // Specify message queue attributes.
    ma.mq_flags = 0;                // blocking read/write
    ma.mq_maxmsg = 16;              // maximum number of messages allowed in queue
    ma.mq_msgsize = sizeof(int);    // messages are contents of an int
    ma.mq_curmsgs = 0;              // number of messages currently in queue

    // Create the message queue with some default settings.
    mq = mq_open("/test_queue", O_RDWR | O_CREAT, 0700, &ma);

    // -1 indicates an error.
    if (mq == -1)
    {
        printf("Failed to create queue.\n");
        status = 1;
    }

    if (status == 0)
    {
        status = mq_send(mq, (char *)(&a), sizeof(int), 1);
    }

    if (status == 0)
    {
        status = mq_receive(mq, (char *)(&b), sizeof(int), NULL);
    }

    if ((status == 0) && (mq_close(mq) == -1))
    {
        printf("Error closing message queue.\n");
        status = 1;
    }

    if ((status == 0) && (mq_unlink("test_queue") == -1))
    {
        printf("Error deleting message queue.\n");
        status = 1;
    }

    printf("a = %d, b = %d\n", a, b);

    return status;
} 

回答by Amardeep AC9MF

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <stdio.h>
#include <stdlib.h>
#define MAXSIZE     128

void die(char *s)
{
  perror(s);
  exit(1);
}

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


void main()
{
    int msqid;
    key_t key;
    struct msgbuf rcvbuffer;

    key = 1234;

    if ((msqid = msgget(key, 0666)) < 0)
      die("msgget()");


     //Receive an answer of message type 1.
    if (msgrcv(msqid, &rcvbuffer, MAXSIZE, 1, 0) < 0)
      die("msgrcv");

    printf("%s\n", rcvbuffer.mtext);
    exit(0);
}

回答by user2482511

mq_send(mq, (char *)(&a), sizeof(int), 1)copies sizeof(int)bytes from buffer &ain this case, it does not carry the pointer of variable a, but carries the value of variable afrom one process to another process. Implementation is right.

mq_send(mq, (char *)(&a), sizeof(int), 1)在这种情况下sizeof(int)从缓冲区复制字节&a,它不携带变量的指针a,而是将变量的值a从一个进程携带到另一个进程。执行是对的。

回答by parasrish

Code as below for your reference:

代码如下供您参考:

IPC_msgq_rcv.c

IPC_msgq_rcv.c

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAXSIZE     128

void die(char *s)
{
  perror(s);
  exit(1);
}

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

main()
{
    int msqid;
    int msgflg = IPC_CREAT | 0666;
    key_t key;
    struct msgbuf sbuf;
    size_t buflen;

    key = 1234;

    if ((msqid = msgget(key, msgflg )) < 0)   //Get the message queue ID for the given key
      die("msgget");

    //Message Type
    sbuf.mtype = 1;

    printf("Enter a message to add to message queue : ");
    scanf("%[^\n]",sbuf.mtext);
    getchar();

    buflen = strlen(sbuf.mtext) + 1 ;

    if (msgsnd(msqid, &sbuf, buflen, IPC_NOWAIT) < 0)
    {
        printf ("%d, %ld, %s, %d \n", msqid, sbuf.mtype, sbuf.mtext, (int)buflen);
        die("msgsnd");
    }

    else
        printf("Message Sent\n");

    exit(0);
}

IPC_msgq_send.c

IPC_msgq_send.c

##代码##

Compile each of the source files, to get a writer-executable and reader-executable. As below::

编译每个源文件,以获得写入器可执行文件和读取器可执行文件。如下::

gcc -o MQsender IPC_msgq_send.c

gcc -o MQreceiver IPC_msgq_rcv.c

gcc -o MQsender IPC_msgq_send.c

gcc -o MQreceiver IPC_msgq_rcv.c

Executing each of the binaries, you can send the message and read the message from the message queue. Also, try to see the message queue state, by running command (at different states of queue):

执行每个二进制文件,您可以发送消息并从消息队列中读取消息。另外,尝试通过运行命令(在队列的不同状态下)查看消息队列状态:

ipcs -q

ipcs -q

For your linux system, you can know all the details of the IPC mechanisms and available queues etc, by using:

对于您的 linux 系统,您可以通过使用以下命令了解 IPC 机制和可用队列等的所有详细信息:

ipcs -a

ipcs -a

Reference Blog

参考博客