首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用thread::detach时,如何检查线程是否已完成

使用thread::detach时,如何检查线程是否已完成
EN

Stack Overflow用户
提问于 2021-01-20 22:35:08
回答 1查看 49关注 1票数 0

我正在尝试做一种“运行检查”,以避免一次多次运行一个函数,它是为了我的另一个项目。我必须使用while()detach(),问题是我真的不知道如何检查线程是否为joinable(),因为当我不这样做时,错误会出现:Unhandled exception at 0x7632A842 in dasd.exe: Microsoft C++ exception: std::system_error at memory location 0x009BF614.但当我使用下面的代码时,我没有得到错误,但是循环不会工作

代码语言:javascript
复制
#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);
    }
}

输出为:

代码语言:javascript
复制
1
1
1
done
1
good
0
0
.......

问题是:我如何才能让成功的循环避免错误?我尝试了很长一段时间,我认为这是关于一些我不知道的事情…

提前谢谢你

EN

回答 1

Stack Overflow用户

发布于 2021-01-20 22:45:47

detach()了。

人们使用detach()的频率太高了。

它应该只在相对较少的情况下使用。在main结束后运行线程不是一个好主意,如果没有与线程结束的正式同步,防止这种情况基本上是不可能的。

使用detach()ed线程有两种方法可以做到这一点-- std::promise_at_thread_exit方法,或者使用特定于操作系统的API。

线程池可能就是您想要的。

代码语言:javascript
复制
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;
};

大概是这样的东西。

然后创建一个单线程线程池,并将任务推入其中。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65811630

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档