文章目录
0. 引言
本文实现一个简单的 Linux 消息传递机制,通过优先级队列、线程安全的消息队列和同步异步机制,模拟 Windows 中的 SendMessage
和 PostMessage
功能。
SendMessage
和 PostMessage
的主要区别在于:
SendMessage
是同步消息发送机制,调用线程会阻塞,直到目标线程处理完消息并返回结果。PostMessage
是异步消息发送机制,消息会立即被放入消息队列,调用线程不会等待消息处理的完成。
1. 设计思路
实现 SendMessage
和 PostMessage
的目标是让两个或多个线程能够通过消息传递进行通信,尤其是在一个线程中发送消息,另一个线程异步或同步地处理这些消息。设计要点:
-
消息结构的定义:设计一个通用的消息结构,包含消息的类型、参数和返回值。消息类型区分同步消息(
SendMessage
)和异步消息(PostMessage
)。 -
消息队列的使用:通过一个线程安全的消息队列(
MessageQueue
)来存储和管理消息。消息队列的线程安全性可以通过使用互斥锁(std::mutex
)和条件变量(std::condition_variable
)来实现。 -
同步与异步消息处理:通过
std::promise
和std::future
实现同步消息的返回值,而异步消息则直接丢入队列,无需返回结果。 -
优先级管理:为了确保同步消息的优先处理,我们可以使用
std::priority_queue
来存储消息,将同步消息的优先级设置为更高,从而确保SendMessage
被优先处理。 -
消息处理线程:独立的消息处理线程负责从队列中取出消息并进行处理。通过不断循环地从队列中取出消息,确保消息得到及时处理。
2. 完整代码
#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <queue>
#include <functional>
#include <future>
#include <memory>
#include <chrono>
// 定义消息类型
enum class MessageType {
kSync, // 同步消息(SendMessage)
kAsync // 异步消息(PostMessage)
};
// 消息结构体
struct Message {
int msg_id;
int w_param;
int l_param;
std::shared_ptr<std::promise<int>> promise_ptr;
MessageType type;
// 用于优先级队列排序,确保同步消息优先处理
bool operator<(const Message& other) const {
return type > other.type; // 同步消息的优先级高
}
};
// 消息队列类,线程安全
class MessageQueue {
public:
// 添加消息到队列
void Enqueue(const Message& msg) {
std::lock_guard<std::mutex> lock(mtx_);
queue_.push(msg);
cv_.notify_one(); // 唤醒消息处理线程
}
// 从队列中取出消息
Message Dequeue() {
std::unique_lock<std::mutex> lock(mtx_);
cv_.wait(lock, [this] {
return !queue_.empty() || terminate_flag_; });