我正在尝试做一种“运行检查”,以避免一次多次运行一个函数,它是为了我的另一个项目。我必须使用while()和detach(),问题是我真的不知道如何检查线程是否为joinable(),因为当我不这样做时,错误会出现:Unhandled exception at 0x7632A842 in dasd.exe: Microsoft C++ exception: std::system_error at memory location 0x009BF614.但当我使用下面的代码时,我没有得到错误,但是循环不会工作
#include <future>
#include <thread>
#include <chrono>
#include <iostream>
using namespace std::chrono_literals;
void Thing()
{
std::this_thread::sleep_for(3s);
std::cout << "done\n";
}
int main()
{
std::packaged_task<void()> task(Thing);
auto future = task.get_future();
std::thread ac(std::move(task));
while (true)
{
std::cout << ac.joinable() << std::endl;
if (future.wait_for(1ms) == std::future_status::ready && ac.joinable())
{
ac.detach();
std::cout << "good\n";
}
std::this_thread::sleep_for(1s);
}
}输出为:
1
1
1
done
1
good
0
0
.......问题是:我如何才能让成功的循环避免错误?我尝试了很长一段时间,我认为这是关于一些我不知道的事情…
提前谢谢你
发布于 2021-01-20 22:45:47
别detach()了。
人们使用detach()的频率太高了。
它应该只在相对较少的情况下使用。在main结束后运行线程不是一个好主意,如果没有与线程结束的正式同步,防止这种情况基本上是不可能的。
使用detach()ed线程有两种方法可以做到这一点-- std::promise的_at_thread_exit方法,或者使用特定于操作系统的API。
线程池可能就是您想要的。
template<class T>
struct threadsafe_queue {
std::optional<T> try_pop();
T wait_and_pop();
void push(T);
std::deque<T> pop_all();
private:
mutable std::mutex m;
std::condition_variable cv;
std::deque<T> data;
};
struct thread_pool {
explicit thread_pool( std::size_t number_of_threads );
std::size_t thread_count() const;
void add_thread(std::size_t n=1);
void abort_all_tasks_and_threads();
void wait_for_empty_queue();
~thread_pool();
template<class F>
std::future<std::invoke_result_t<F>> add_task( F f );
private:
using task=std::future<void()>; // or std::packaged_task<void> or something custom
std::vector<std::thread> threads;
threadsafe_queue< task > tasks;
};大概是这样的东西。
然后创建一个单线程线程池,并将任务推入其中。
https://stackoverflow.com/questions/65811630
复制相似问题