#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <thread>
#include <queue>
#include <mutex>
#include <condition_variable>
#include <functional>
#include <chrono>
#include <random>
#include <ctime>
#include <thread>
class RandomTimer;
// 获取当前时间的字符串表示
std::string getCurrentTime() {
auto now = std::chrono::system_clock::now();
std::time_t time = std::chrono::system_clock::to_time_t(now);
std::string timeStr = std::ctime(&time);
// 去除末尾的换行符
timeStr.erase(timeStr.length() - 1);
return timeStr;
}
template <typename T, typename Priority>
class AsyncMessageQueue
{
public:
AsyncMessageQueue()
{
std::cout << __func__ << "[" << std::this_thread::get_id() << "] " << "[" << getCurrentTime() << "] " << "AsyncMessageQueue" << std::endl;
}
void WriteQ(const T& message, Priority priority = 0)
{
std::cout << __func__ << "[" << std::this_thread::get_id() << "] " << "[" << getCurrentTime() << "] " << "WriteQ" << message << std::endl;
std::lock_guard<std::mutex> lock(mtx);
messageQueue.push(std::make_pair(message, priority));
cv.notify_one();
}
T ReadQ()
{
std::cout << __func__ << "[" << std::this_thread::get_id() << "] " << "[" << getCurrentTime() << "] " << "ReadQ" << std::endl;
std::unique_lock<std::mutex> lock(mtx);
cv.wait(lock, [this] { return !messageQueue.empty(); });
auto message = messageQueue.top().first;
messageQueue.pop();
return message;
}
bool empty()
{
return messageQueue.empty();
}
private:
std::priority_queue<std::pair<T, Priority>,
std::vector<std::pair<T, Priority>>,
std::function<bool(const std::pair<T, Priority>&, const std::pair<T, Priority>&)>> messageQueue{
[](const std::pair<T, Priority>& lhs, const std::pair<T, Priority>& rhs) {
return lhs.second > rhs.second;
} };
std::mutex mtx;
std::condition_variable cv;
};
template <typename T, typename Priority = int>
class ThreadWithAsyncMessage
{
public:
ThreadWithAsyncMessage() :randomTimer(3, 5), stop(false)
{
thread = std::thread(&ThreadWithAsyncMessage::ThreadFunction, this);
}
~ThreadWithAsyncMessage()
{
stop = true;
thread.join();
}
void WriteQ(const T& message, Priority priority = 0)
{
messageQueue.WriteQ(message, priority);
}
private:
void ThreadFunction()
{
while (true)
{
if (!messageQueue.empty())
{
T message = messageQueue.ReadQ();
// 处理接收到的消息
std::cout << __func__ << "[" << std::this_thread::get_id() << "] " <<"[" << getCurrentTime() << "] " << "Received message: " << message << std::endl;
//模拟处理消息的时间1~3秒
int time = randomTimer.WaitRandomTime();
std::cout << __func__ << "[" << std::this_thread::get_id() << "] " << "[" << getCurrentTime() << "] " << "Waited " << time << "seconds" << std::endl;
}
else if (stop)
{
break;
}
}
}
AsyncMessageQueue<T, Priority> messageQueue;
std::thread thread;
bool stop;
RandomTimer randomTimer;
};
class RandomTimer {
private:
std::random_device rd;
std::mt19937 gen;
std::uniform_int_distribution<int> dis;
public:
RandomTimer(int minSeconds, int maxSeconds) : gen(rd()), dis(minSeconds, maxSeconds) {
}
int WaitRandomTime() {
int randomSeconds = dis(gen);
std::this_thread::sleep_for(std::chrono::seconds(randomSeconds));
return randomSeconds;
}
};
int main()
{
ThreadWithAsyncMessage<std::string, int> worker;
// 主线程发送消息给工作线程
worker.WriteQ("Message 1", 2);
std::this_thread::sleep_for(std::chrono::seconds(1)); // 模拟任务执行时间
worker.WriteQ("Message 2", 1);
std::this_thread::sleep_for(std::chrono::seconds(1)); // 模拟任务执行时间
worker.WriteQ("Message 3", 3);
std::this_thread::sleep_for(std::chrono::seconds(1)); // 模拟任务执行时间
worker.WriteQ("Message 4", 0);
std::this_thread::sleep_for(std::chrono::seconds(1)); // 模拟任务执行时间
worker.WriteQ("Message 5", 2);
return 0;
}
C++ 带优先级的异步队列的工作线程
于 2023-05-26 10:15:12 首次发布