自学内容网 自学内容网

Linux 消息队列

在Linux中,线程间消息队列可以通过使用System V消息队列或POSIX消息队列来实现。

  1. 使用System V消息队列: System V消息队列是一种基于IPC(Inter-process Communication,进程间通信)的通信机制,可以用于进程或线程间的通信。下面是使用System V消息队列实现线程间通信的步骤:

a. 创建消息队列: 可以使用msgget()函数来创建一个新的消息队列。例如:

key_t key = ftok("path_to_key_file", 'A');
int msgid = msgget(key, IPC_CREAT | 0666);

b. 发送消息: 使用msgsnd()函数向消息队列发送消息。例如:

struct message {
    long mtype;
    char mtext[256];
};

struct message msg;
msg.mtype = 1;
strcpy(msg.mtext, "Hello, world!");

msgsnd(msgid, &msg, sizeof(msg.mtext), 0);

c. 接收消息: 使用msgrcv()函数从消息队列接收消息。例如:

struct message msg;
msgrcv(msgid, &msg, sizeof(msg.mtext), 1, 0);

printf("Received message: %s\n", msg.mtext);

  1. 使用POSIX消息队列: POSIX消息队列是Linux中提供的另一种消息队列实现方式,它提供了更多的功能和灵活性。下面是使用POSIX消息队列实现线程间通信的步骤:

a. 创建消息队列: 可以使用mq_open()函数创建一个新的消息队列。例如:

mqd_t mq = mq_open("/my_queue", O_CREAT | O_RDWR, 0666, NULL);

b. 发送消息: 使用mq_send()函数向消息队列发送消息。例如:

char msg[] = "Hello, world!";
mq_send(mq, msg, sizeof(msg), 0);

c. 接收消息: 使用mq_receive()函数从消息队列接收消息。例如:

char buf[256];
mq_receive(mq, buf, sizeof(buf), NULL);

printf("Received message: %s\n", buf);

需要注意的是,POSIX消息队列的名称在文件系统中是可见的,可以使用路径名来创建和打开消息队列。

整体实现:

发送到队列中去

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

#define MSGSZ 512
struct  msg_buffer
{
    long   mtype;
    char   mtext[MSGSZ];
    int    age;
    double  many;
}msg_buf;


int main(){
    key_t ftok_key=ftok("./msg1", 'b');
    //创建消息队列
    int msgget_id=msgget(ftok_key, IPC_CREAT|0666);

    //写入队列
    msg_buf.mtype=1;
    msg_buf.age=168;
    msg_buf.many=123.456;
    strcpy(msg_buf.mtext, "“我今天去超市,结果发现超市里没有超市");
    //key  指针类型的结构体  消息正文大小 发送标志 
    int msgend_stat=msgsnd(msgget_id, &msg_buf, sizeof(msg_buf)-sizeof(msg_buf.mtype), 0);
    
    msg_buf.mtype=8;
    strcpy(msg_buf.mtext, "我昨天梦见自己醒来了,结果今天真的醒来了");
    //key  指针类型的结构体  消息正文大小 发送标志 
    int msgend_stat1=msgsnd(msgget_id, &msg_buf, sizeof(msg_buf.mtext), 0);

    msg_buf.mtype=5;
    strcpy(msg_buf.mtext, "我试图在网上搜索‘如何上网’,结果电脑告诉我‘无法连接到互联网’");
    //key  指针类型的结构体  消息正文大小 发送标志 
    int msgend_stat2=msgsnd(msgget_id, &msg_buf, sizeof(msg_buf.mtext), 0);


    return 0;
}

接收

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

#define MSGSZ 512
struct  msg_buffer
{
    long   mtype;
    char   mtext[MSGSZ];
    int    age;
    double  many;
}msg_buf;

int main() {
    // 创建唯一的key
   key_t ftok_key = ftok("./msg1", 'b');

    // 访问消息队列
   int  msgid = msgget(ftok_key, 0666 | IPC_CREAT);
    if (msgid == -1) {
        perror("msgget error");
        exit(1);
    }

    // 接收消息
    //key 接收的大小   读取类型为msgtyp的第一条消息  0: 阻塞接收,直到有消息到达
    if (msgrcv(msgid, &msg_buf, sizeof(msg_buf.mtext), 8, 0) == -1) {
        perror("msgrcv error");
        exit(1);
    }
    printf("msg_buf received by child process: %s\n", msg_buf.mtext);

sleep(1);
    if (msgrcv(msgid, &msg_buf, sizeof(msg_buf)-sizeof(msg_buf.mtype), 1, 0) == -1) {
        perror("msgrcv error");
        exit(1);
    }
    printf("msg_buf received by child process: %s  岁是%d 钱是:%.3fd\n", msg_buf.mtext, msg_buf.age, msg_buf.many);
sleep(1);

    if (msgrcv(msgid, &msg_buf, sizeof(msg_buf.mtext), 5, 0) == -1) {
        perror("msgrcv error");
        exit(1);
    }
    printf("msg_buf received by child process: %s\n", msg_buf.mtext);
sleep(1);

    // 删除消息队列
    if (msgctl(msgid, IPC_RMID, NULL) == -1) {
        perror("msgctl error");
        exit(1);
    }

    return 0;
}


原文地址:https://blog.csdn.net/m0_58341340/article/details/143662952

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!