gpt4 book ai didi

c++ - 等待线程超时 : freeze

转载 作者:太空宇宙 更新时间:2023-11-04 13:28:20 24 4
gpt4 key购买 nike

我现在什么都不懂。假设我有下一段代码(简化版):

#include <iostream>
#include <thread>
#include <condition_variable>
#include <mutex>
#include <chrono>

const auto k_sleep = std::chrono::seconds{3};
const auto k_wait = std::chrono::seconds{1};
const auto k_repeats = 20u;

void test()
{
std::mutex m;
std::condition_variable c;
bool processed = false;

std::thread worker{[&]() {
std::this_thread::sleep_for(k_sleep);

std::unique_lock<std::mutex> lock(m);
processed = true;
lock.unlock();
c.notify_one();
}};

std::unique_lock<std::mutex> lock(m);
if(c.wait_for(lock, k_wait, [&processed]() {
return processed;
}))
{
worker.join();
std::cout << "done" << std::endl;
}
else
{
worker.detach();
std::cout << "timeout" << std::endl;
}
}

int main()
{
for(auto i = 0u; i < k_repeats; ++i)
test();
}

几个问题:

  • 有没有死锁?
  • 我是否正确使用了 condition_variable(以及与 thread 相关的所有其他内容)?
  • 有没有UB?
  • 如果一切正常,timeout 会打印多少次?

如您所见,我正在运行线程并等待它(使用 condition_variable)一段时间。等待时间小于线程的执行时间。

同时使用 VC++(Visual Studio 2015,v 19.00.23026)和 g++(v 4.8.2)我打印了 timeout 2 次,然后我卡在了 worker.join () 在调试器下。如果我将 k_sleep 增加到一些大的东西(相对于 k_wait 小循环计数),例如,30 秒 - 一切都会好起来的。

那么,为什么会这样?如果我做错了什么,请向我解释正确的方法。谢谢

最佳答案

你的内存管理有问题:

  1. 在传递给新线程的 lambda 中通过引用捕获变量。
  2. 所有变量(mcprocessed)都分配在堆栈上,当您分离 a 时它们将超出范围工作线程。所以,当线程醒来时,它会访问垃圾。

因此,您需要在堆上分配数据并确保不通过引用捕获变量。我总是喜欢将数据显式传递到 std::thread

#include <iostream>
#include <thread>
#include <condition_variable>
#include <mutex>
#include <chrono>
#include <memory>

const auto k_sleep = std::chrono::seconds{ 3 };
const auto k_wait = std::chrono::seconds{ 1 };
const auto k_repeats = 20u;


struct Data
{
std::mutex m;
std::condition_variable c;
bool processed = false;
};

void test()
{
auto data = std::make_shared<Data>();

auto run = [](std::shared_ptr<Data> i_data) {
std::this_thread::sleep_for(k_sleep);

std::unique_lock<std::mutex> lock(i_data->m);
i_data->processed = true;
lock.unlock();
i_data->c.notify_one();
};

std::thread worker{ run, data };

std::unique_lock<std::mutex> lock(data->m);
if (data->c.wait_for(lock, k_wait, [&data]() {
return data->processed;
}))
{
worker.join();
std::cout << "done" << std::endl;
}
else
{
worker.detach();
std::cout << "timeout" << std::endl;
}
}

int main()
{
for (auto i = 0u; i < k_repeats; ++i)
test();
}

关于c++ - 等待线程超时 : freeze,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32536966/

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