gpt4 book ai didi

c++ - 我可以分离内部 std::future 线程吗?

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:15:06 27 4
gpt4 key购买 nike

考虑以下代码:

template <typename func_t, typename ... Args>
auto waiter (func_t func, const Args &... args) -> decltype(func(args...)) {
const static std::chrono::milliseconds max_time(10);
auto task = std::packaged_task<decltype(func(args...))()>(std::bind(func, args...));
auto handle = task.get_future();
std::thread th(std::move(task)); // here
if (handle.wait_for(max_time) == std::future_status::timeout) {
th.detach(); // and here
throw std::runtime_error("timeout");
} else { // and here
th.detach();
return handle.get();
}
}

我可以安全地从 std::future 中取出内部 std::thread 并将其分离吗?我想这很明显是UB。 waiter() 函数被设计为获取任何可调用对象,调用它并在任何情况下停止工作

  1. 达到超时
  2. 函数停止工作并返回结果

是真的。我尝试了很多方法来做到这一点,但总是有问题。我意识到问题是 C++14 没有进程支持。第一次尝试:

template <typename func_t, typename ... Args>
auto waiter (func_t func, const Args &... args) -> decltype(func(args...)) {
const static std::chrono::milliseconds max_time(10);
decltype(func(args...)) result;
std::mutex mtx;
std::unique_lock<std::mutex> lock(mtx);
std::condition_variable cv;

thread th([&] {
result = func(args...);
cv.notify_all();
});

auto waiting_result = cv.wait_for(lock, max_time);
th.detach();
if (waiting_result == std::cv_status::timeout) {
throw std::runtime_error("timeout");
}
return result;
}

这里的问题是在抛出异常后,std::thread th 仍在运行,引用被杀死。第二次尝试:

template <typename func_t, typename ... Args>
auto waiter (func_t func, const Args &... args) -> decltype(func(args...)) {
const static std::chrono::milliseconds max_time(10);
auto handle = std::async(std::launch::async, func, args ...);
if (handle.wait_for(max_time) == std::future_status::timeout) {
throw std::runtime_error("timeout");
} else {
return handle.get();
}
}

这里的问题是(据我所知)std::async::~async() 调用某种std::thread::join() 在它的内部线程上,主线程仍在等待 std::asynchttp://melpon.org/wandbox/permlink/Cyd2hYJCQSIxETqL傻一个。

最佳答案

您可以像第一次尝试那样分离线程,但是,正如您所说,线程将继续运行分离直到它自己完成。

第二次尝试的问题是 std::async 返回的 std::future 有点特殊,因为它的析构函数将 block until the thread finishes execution (不同于常规 std::future 的析构函数)

恐怕在 C++ 中不可能安全地终止单个线程而不杀死所有线程。问题是由于在执行期间的任意点安全地展开堆栈的困难而产生的。如果比方说,展开应该发生在不合适的地方,比如 ctor 或 dtor,这将违反对象存储持续时间的规则。

参见 this answer了解更多详情。

关于c++ - 我可以分离内部 std::future 线程吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34687583/

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