linux 消息队列例子

/author:DriverMonkey
//phone:13410905075
//mail:bookworepeng@Hotmail.com
//qq:196568501

#include <pthread.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>

#include <string.h>

#include <iostream>

#define MAX_SEND_SIZE 80
#define RETURN_MSG_TYPE 0XAA
#define SEND_MSG_TYPE 0X55

using namespace std;

struct mymsgbuf {
long mtype;
char mtext[MAX_SEND_SIZE];
};


static void *thread_GUI(void *arg);
static void *thread_logic(void *arg);

static int init_message(unsigned char key);
static void send_message(int qid,
                            struct mymsgbuf *qbuf,
                            long type,
                            const void *text,
                            int size);
static int read_message(int qid, struct mymsgbuf *qbuf, long type);
static void remove_queue(int qid);

static int message_id = 0;

int main ()
{
    pthread_t thread_GUI_id = 0;
    pthread_t thread_logic_id = 0;

    message_id = init_message('g');
    
    pthread_create (&thread_GUI_id, NULL, &thread_GUI, NULL);
    pthread_create (&thread_logic_id, NULL, &thread_logic, NULL);

    pthread_join (thread_GUI_id, NULL);
    pthread_join (thread_logic_id, NULL);
 
    return 0;
}

static void *thread_GUI(void *arg)
{
    int sleep_count = 0;
    mymsgbuf send_buf;
    
    sleep_count = 10;
    char send_v = 0;

    while(sleep_count--)
    {
        send_v++;
        send_message(message_id, &send_buf , SEND_MSG_TYPE, &send_v,sizeof(send_v));
        //cout<<"thead_GUI: sleep_count = "<<sleep_count<<endl;
        //sleep(1);
    }
}
static void *thread_logic(void *arg)
{
    int sleep_count = 0;
    mymsgbuf recive_buf;

    sleep_count = 10;
    while(sleep_count--)
    {
        //cout<<"thread_logic: sleep_count = "<<sleep_count<<endl;
        read_message(message_id,&recive_buf, SEND_MSG_TYPE);
        //sleep(1);
    }
}

int init_message(unsigned char key)
{
    int id = 0;
    
    key = ftok(".", key);

    id = msgget(key, IPC_CREAT|0777);
    if(id == (-1))
        while(1);// should never in
        
    return id;
}


void send_message(int qid,
                            struct mymsgbuf *qbuf,
                            long type,
                            const void *text,
                            int size)
{
    qbuf->mtype = type;
    memcpy(qbuf->mtext, text,size);
    cout<<"send = " <<(int)qbuf->mtext[0]<<endl;
    if((msgsnd(qid, (struct msgbuf *)qbuf,size,NULL) == -1))
        while(1);//shoud never in

    qbuf->mtype = type;
    msgrcv(qid, (struct msgbuf *)qbuf, MAX_SEND_SIZE, RETURN_MSG_TYPE, 0);
    cout<<"send return= " << (int)qbuf->mtext[0]<<endl;
    cout<<qbuf->mtext<<endl;
}

int read_message(int qid, struct mymsgbuf *qbuf, long type)
{
    int read_size = 0;
    static int temp = 100;
    
    qbuf->mtype = type;
    temp++;
    read_size = msgrcv(qid, (struct msgbuf *)qbuf, MAX_SEND_SIZE, type, 0);
    cout<<"read = " << (int)qbuf->mtext[0]<<endl;
    char const *return_message = "message_ok";
    strcpy(qbuf->mtext, return_message);
    
    qbuf->mtext[0] = temp++;
    qbuf->mtype = RETURN_MSG_TYPE;
    msgsnd(qid, (struct msgbuf *)qbuf,strlen(return_message)+1,NULL);
    cout<<"read return ="<<(int)qbuf->mtext[0]<<endl;
}


void remove_queue(int qid)
{

}
Linux系统中,线程间通过消息队列通信是一种常见的并发控制机制,它允许一个线程将数据放入队列,而另一个线程则可以从队列中取出并处理数据。下面是一个简单的示例,演示了如何使用`msg_queue`库在两个线程之间传递消息: 首先,创建一个消息队列: ```bash #include <sys/msg.h> #include <stdlib.h> int create_msg_queue() { key_t key = ftok("/tmp/myqueue", 'M'); // 使用特定路径和字符作为键 struct msg_queue *mq = msgget(key, IPC_CREAT | 0644); if (mq == -1) { perror("msgget failed"); return -1; } return mq; } ``` 然后,定义发送者线程(sender_thread.c): ```c void sender_thread(int mqdes) { int msg_num = 5; // 消息数量 for (int i = 0; i < msg_num; ++i) { char message[] = "Message from sender, number: " + i; ssize_t bytes_sent = msgsnd(mqdes, message, strlen(message), 0); if (bytes_sent == -1) { perror("msgsnd failed"); } } } ``` 接着,定义接收者线程(receiver_thread.c): ```c void receiver_thread(int mqdes) { char buffer[1024]; while (1) { ssize_t bytes_received = msgrcv(mqdes, buffer, sizeof(buffer), 0, 0); // 阻塞接收直到有消息可用 if (bytes_received > 0) { printf("Received message: %s\n", buffer); } else if (bytes_received == -1 && errno == EAGAIN) { // 如果没有消息,检查是否是因为阻塞 sleep(1); // 等待1秒再试 } else { perror("msgrcv failed"); break; } } } ``` 最后,在主程序中启动线程: ```c int main() { int mqdes = create_msg_queue(); if (mqdes == -1) { return -1; } pthread_t sender_pid, receiver_pid; if (pthread_create(&sender_pid, NULL, &sender_thread, (void*)mqdes)) { perror("pthread_create for sender failed"); return -1; } if (pthread_create(&receiver_pid, NULL, &receiver_thread, (void*)mqdes)) { perror("pthread_create for receiver failed"); return -1; } pthread_join(sender_pid, NULL); pthread_join(receiver_pid, NULL); msgctl(mqdes, MSQRM semiclassical, NULL); // 删除消息队列 close(mqdes); return 0; } ``` 运行这个程序,你会看到发送者线程向接收者线程发送消息,而接收者线程在接收到消息后打印出来。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值