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

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

我正在寻找一些很好的代码示例,可以显示如何以正确和正确的方式完成,也许是一个howto。

Solutions Collecting From Web of "如何在基于Linux的系统的ac程序中使用mqueue?"

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

服务器的代码:

#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] = '\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; } 

客户端的代码:

 #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; } 

共同的标题:

 #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_ */ 

编译

 gcc -o server server.c -lrt gcc -o client client.c -lrt 
 #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; } 

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

代码如下,供您参考:

IPC_msgq_rcv.c

 #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); } 

IPC_msgq_send.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); } 

编译每个源文件,以获得一个作者可执行文件和读者可执行文件。 如下::

gcc -o MQsender IPC_msgq_send.c

gcc -o MQreceiver IPC_msgq_rcv.c

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

ipcs -q

对于你的linux系统,你可以通过以下方式了解IPC机制和可用队列等的所有细节:

ipcs -a

参考博客