using clock_type = std::chrono::system_clock; struct message { clock_type::time_point when; std::function<void()> callback; std::string param; }; class message_loop { public: message_loop(): _stop(false) { // } message_loop(const message_loop&) = delete; message_loop& operator=(const message_loop&) = delete; void run() { while (!_stop) { auto msg = wait_one(); msg.callback(); } } void quit() { post({clock_type::now(), this{ _stop = true; } }); } void post(std::function<void()> callable) { post({clock_type::now(), std::move(callable)}); } void post(std::function<void()> callable, std::chrono::milliseconds delay) { post({clock_type::now() + delay, std::move(callable)}); } private: struct msg_prio_comp { inline bool operator() (const message& a, const message& b) { return a.when > b.when; } }; using queue_type = std::priority_queue<message, std::vector<message>, msg_prio_comp>; std::mutex _mtx; std::condition_variable _cv; queue_type _msgs; bool _stop; void post(message msg) { auto lck = acquire_lock(); _msgs.emplace(std::move(msg)); _cv.notify_one(); } std::unique_lockstd::mutex acquire_lock() { return std::unique_lockstd::mutex(_mtx); } bool idle() const { return _msgs.empty(); } const message& top() const { return _msgs.top(); } message pop() { auto msg = top(); _msgs.pop(); return msg; } message wait_one() { while (true) { auto lck = acquire_lock(); if (idle()) _cv.wait(lck); else if (top().when <= clock_type::now()) return pop(); else { _cv.wait_until(lck, top().when); // 可能是新消息到达,再循环一次看看 } } } }; int main(int argc, char *argv[]) { using namespace std; using namespace std::chrono; message_loop *pLoop = new message_loop; thread th(pLoop{ pLoop->run(); }); cout << "POST 1"<<endl;; pLoop->post({ cout << "1"<<endl; }); cout << "POST 2"<<endl;; pLoop->post({ cout << "2"<<endl; }, milliseconds(500)); cout << "POST 3"<<endl;; pLoop->post({ cout << "3"<<endl; }); cout << "POST 4"<<endl;; pLoop->post({ cout << "4"<<endl; }, milliseconds(1000)); this_thread::sleep_for(milliseconds(1500)); // pLoop->quit(); cout << "Quit"<<endl; th.join(); cout << "here"<<endl; } 请优化一下,可以传参
时间: 2024-02-04 15:03:32 浏览: 83
C++11中的时间库std::chrono(引发关于时间的思考)
可以将 message 结构体中的 param 字段用于传递参数,并相应地修改 post 函数和 wait_one 函数。具体代码如下:
```
using clock_type = std::chrono::system_clock;
struct message {
clock_type::time_point when;
std::function<void(const std::string&)> callback;
std::string param;
};
class message_loop {
public:
message_loop() : _stop(false) {}
message_loop(const message_loop&) = delete;
message_loop& operator=(const message_loop&) = delete;
void run() {
while (!_stop) {
auto msg = wait_one();
msg.callback(msg.param);
}
}
void quit() {
post({clock_type::now(), [](const std::string&) {}}, "");
_stop = true;
}
void post(std::function<void(const std::string&)> callable, const std::string& param) {
post({clock_type::now(), std::move(callable), param});
}
void post(std::function<void(const std::string&)> callable, std::chrono::milliseconds delay, const std::string& param) {
post({clock_type::now() + delay, std::move(callable), param});
}
private:
struct msg_prio_comp {
inline bool operator() (const message& a, const message& b) {
return a.when > b.when;
}
};
using queue_type = std::priority_queue<message, std::vector<message>, msg_prio_comp>;
std::mutex _mtx;
std::condition_variable _cv;
queue_type _msgs;
bool _stop;
void post(message msg) {
auto lck = acquire_lock();
_msgs.emplace(std::move(msg));
_cv.notify_one();
}
std::unique_lock<std::mutex> acquire_lock() {
return std::unique_lock<std::mutex>(_mtx);
}
bool idle() const {
return _msgs.empty();
}
const message& top() const {
return _msgs.top();
}
message pop() {
auto msg = top();
_msgs.pop();
return msg;
}
message wait_one() {
while (true) {
auto lck = acquire_lock();
if (idle()) {
_cv.wait(lck);
} else if (top().when <= clock_type::now()) {
auto msg = pop();
return msg;
} else {
_cv.wait_until(lck, top().when);
// 可能是新消息到达,再循环一次看看
}
}
}
};
int main(int argc, char *argv[]) {
using namespace std;
using namespace std::chrono;
message_loop *pLoop = new message_loop;
thread th(pLoop, &message_loop::run);
pLoop->post([](const std::string& param) { cout << "1 " << param << endl; }, "hello");
pLoop->post([](const std::string& param) { cout << "2 " << param << endl; }, milliseconds(500), "world");
pLoop->post([](const std::string& param) { cout << "3 " << param << endl; }, "foo");
pLoop->post([](const std::string& param) { cout << "4 " << param << endl; }, milliseconds(1000), "bar");
this_thread::sleep_for(milliseconds(1500));
pLoop->quit();
th.join();
}
```
阅读全文