gpt4 book ai didi

c++ - 与 std::condition_variable 相比,使用 std::atomic 的方法 wrt 在 C++ 中暂停和恢复 std::thread

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:30:13 26 4
gpt4 key购买 nike

这是一个单独的问题,但与我之前提出的问题有关 here

我正在使用 std::thread在我的 C++不断轮询某些数据并将其添加到缓冲区的代码。我用 C++ lambda像这样启动线程:

StartMyThread() {

thread_running = true;
the_thread = std::thread { [this] {
while(thread_running) {
GetData();
}
}};
}

thread_running是一个 atomic<bool>在类头中声明。这是我的 GetData功能:

GetData() {
//Some heavy logic
}

接下来我还有一个StopMyThread我设置的功能 thread_running为 false 以便它退出 lambda block 中的 while 循环.

StopMyThread() {
thread_running = false;
the_thread.join();
}

据我了解,我可以使用 std::condition_variable 暂停和恢复线程正如所指出的here在我之前的问题中。

但是如果我只使用 std::atomic<bool> 会有缺点吗? thread_running执行或不执行GetData()中的逻辑像下面这样?

GetData() {
if (thread_running == false)
return;
//Some heavy logic
}

与使用 std::condition_variable 的方法相比,这会消耗更多的 CPU 周期吗?如所述 here ?

最佳答案

当您想要有条件地停止或不停止另一个线程时,条件变量很有用。因此,您可能有一个始终运行的“工作”线程,当它注意到它与运行无关时等待。

原子解决方案要求您的 UI 交互与工作线程同步,或者非常复杂的逻辑以异步方式执行。

作为一般规则,您的 UI 响应线程永远不应阻塞工作线程的非就绪状态。

struct worker_thread {
worker_thread( std::function<void()> t, bool play = true ):
task(std::move(t)),
execute(play)
{
thread = std::async( std::launch::async, [this]{
work();
});
}
// move is not safe. If you need this movable,
// use unique_ptr<worker_thread>.
worker_thread(worker_thread&& )=delete;
~worker_thread() {
if (!exit) finalize();
wait();
}
void finalize() {
auto l = lock();
exit = true;
cv.notify_one();
}
void pause() {
auto l = lock();
execute = false;
}
void play() {
auto l = lock();
execute = true;
cv.notify_one();
}
void wait() {
Assert(exit);
if (thread)
thread.get();
}
private:
void work() {
while(true) {
bool done = false;
{
auto l = lock();
cv.wait( l, [&]{
return exit || execute;
});
done = exit; // have lock here
}
if (done) break;
task();
}
}
std::unique_lock<std::mutex> lock() {
return std::unique_lock<std::mutex>(m);
}
std::mutex m;
std::condition_variable cv;
bool exit = false;
bool execute = true;
std::function<void()> task;
std::future<void> thread;
};

或类似的东西。

这拥有一个线程。只要处于 play() 模式,线程就会重复运行任务。如果您在下次 task() 完成时 pause(),工作线程将停止。如果您在 task() 调用完成之前 play(),它不会注意到 pause()

唯一的等待是销毁 worker_thread,它会自动通知工作线程它应该退出并等待它完成。

您也可以手动.wait().finalize().finalize() 是异步的,但如果您的应用程序正在关闭,您可以提前调用它并给工作线程更多时间来清理,而主线程在其他地方清理东西。

.finalize() 不可逆

代码未经测试。

关于c++ - 与 std::condition_variable 相比,使用 std::atomic 的方法 wrt 在 C++ 中暂停和恢复 std::thread,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40553609/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com