linux 线程间消息队列实现
时间: 2023-05-25 07:03:50 浏览: 259
在 Linux 中实现线程间的消息队列,我们可以使用 POSIX 消息队列(POSIX message queues)和 SysV 队列(System V Message Queue)。
1. POSIX 消息队列
POSIX 消息队列是 POSIX 线程提供的一个进程间通信的方式。一个消息队列包含一个标识符、一个最大队列长度和一个消息队列的缓存区。它类似于管道和消息队列,但它与进程无关。
POSIX 消息队列提供了两个函数 mq_open() 和 mq_send() 来创建队列和发送消息。mq_open() 函数返回类型为 mqd_t(消息队列描述符),它是一个整数,用于后续操作中参考队列。mq_send() 函数用于向队列中发送消息,它需要传递指定的描述符以便发送消息。
以下是 POSIX 消息队列的实现示例:
```
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <mqueue.h>
#define QUEUE_NAME "/my_message_queue"
#define QUEUE_PERMS ((mode_t) 0600)
#define MAX_MSG_SIZE 2048
#define MAX_MSG_NUM 10
void die(char *s){
perror(s);
exit(EXIT_FAILURE);
}
int main(int argc, char *argv[]){
mqd_t qd;
struct mq_attr attr;
attr.mq_flags = 0; //设置队列标志为 0
attr.mq_maxmsg = MAX_MSG_NUM; //设置队列中允许最大的消息数
attr.mq_msgsize = MAX_MSG_SIZE; //设置队列中允许最大的消息大小
/*打开或创建一个新的消息队列*/
qd = mq_open(QUEUE_NAME, O_RDWR | O_CREAT, QUEUE_PERMS, &attr);
if(qd == -1) die("mq_open");
char *msg = "Hello, world.";
size_t msg_len = strlen(msg);
unsigned int priority = 1;
/*将消息发送到队列中*/
if(mq_send(qd, msg, msg_len, priority) == -1) die("mq_send");
mq_close(qd); //关闭消息队列
return 0;
}
```
2. SysV 队列
SysV 队列是 System V IPC 提供的一种线程间通信方式。它提供了 msgget()、msgctl()、msgrcv() 这三个函数来创建队列、控制队列和接收消息。
以下是 SysV 消息队列的实现示例:
```
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#define QUEUE_PERMS 0600
#define BUF_SIZE 256
struct message{
long mtype;
char mtext[BUF_SIZE];
};
int main(int argc, char *argv[]){
key_t key;
int qid;
struct message msg;
/*创建共享目录*/
if((key = ftok(".", 'a')) == -1){
perror("ftok");
exit(1);
}
/*创建消息队列*/
if((qid = msgget(key, QUEUE_PERMS | IPC_CREAT)) == -1){
perror("msgget");
exit(1);
}
/*向消息队列中发送消息*/
msg.mtype = 1;
strncpy(msg.mtext, "Hello, world.", BUF_SIZE-1);
if(msgsnd(qid, &msg, strlen(msg.mtext), IPC_NOWAIT) == -1){
perror("msgsnd");
exit(1);
}
/*释放消息队列*/
if(msgctl(qid, IPC_RMID, NULL) == -1){
perror("msgctl");
exit(1);
}
return 0;
}
```
阅读全文