{ unique_lock<mutex> lck(mtx); ready = true; cv.notify_all(); }
时间: 2024-02-17 18:47:49 浏览: 18
这段代码是典型的 C++11 多线程应用代码,它使用了 std::mutex、std::unique_lock 和 std::condition_variable 来实现了线程同步和通信。其中,mutex 是一个互斥量,用于保证多个线程对共享数据的访问是互斥的;unique_lock 和条件变量 condition_variable 配合使用,可以实现线程的等待和唤醒操作,从而达到线程间的同步和协作。在这段代码中,当 ready 变量设置为 true 时,会通知所有正在等待的线程。
相关问题
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; } 请优化一下,可以传参
可以将 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();
}
```
condition_variable和mutex,并举个例子,告诉我如何使用他们
在++中,通常使用mutex和condition_variable来实现多线程之间的同步和协调。
下面是一个简单的例子,展示了如何使用mutex和condition_variable来实现两个线程之间的同步:
```cpp
#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>
std::mutex mtx;
std::condition_variable cv;
bool ready = false;
void worker_thread() {
// 等待主线程通知
std::unique_lock<std::mutex> lck(mtx);
cv.wait(lck, []{ return ready; });
// 收到通知后执行任务
std::cout << "Worker thread is running." << std::endl;
}
int main() {
// 创建工作线程
std::thread worker(worker_thread);
// 执行一些任务
std::cout << "Main thread is running." << std::endl;
std::this_thread::sleep_for(std::chrono::seconds(1));
// 通知工作线程可以执行任务了
{
std::lock_guard<std::mutex> lck(mtx);
ready = true;
}
cv.notify_one();
// 等待工作线程执行完毕
worker.join();
return 0;
}
```
在这个例子中,我们创建了一个工作线程和一个主线程。工作线程等待主线程通知,只有当主线程通知后,工作线程才会开始执行任务。为了实现这个逻辑,我们使用了mutex和condition_variable。主线程在通知工作线程可以执行任务之前,先获取了mutex的控制权,然后设置`ready`变量为`true`,并使用`cv.notify_one()`来通知工作线程。工作线程在等待通知时,使用`cv.wait()`来阻塞自己并释放mutex的控制权。只有当主线程通知后,它才会收到通知并开始执行任务。
这个例子中,mutex和condition_variable的使用方式是:
- 使用`std::mutex`来创建一个互斥量,用于保护共享资源。在主线程中,我们使用`std::lock_guard`来获取mutex的控制权,并在代码块结束时自动释放mutex的控制权。
- 使用`std::condition_variable`来创建一个条件变量,用于在线程之间传递信号和等待通知。在工作线程中,我们使用`std::unique_lock`来获取mutex的控制权,并使用`cv.wait()`来阻塞自己并释放mutex的控制权。只有当主线程通知后,它才会收到通知并继续执行。在主线程中,我们使用`cv.notify_one()`来通知工作线程可以继续执行了。