简体   繁体   中英

How can I check if thread is done, when using thread::detach

I am trying to make kind of "running check" to avoid running one function multiple times at once it is for my another project. I have to use while() and detach() , the problem is I don't really know how can I check if thread is joinable() , because when I am not doing this this, the error comes out: Unhandled exception at 0x7632A842 in dasd.exe: Microsoft C++ exception: std::system_error at memory location 0x009BF614. but when I use code below I am getting no errors, but loop won't work

#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);
    }
}

the output is:

1
1
1
done
1
good
0
0
.......

the question is: how can i make successful loop avoiding errors? I am trying for such as long time, and i think it is about something what i just don't know...

Thank You in advance

Don't detach() .

People use detach() far, far too often.

It should only be used in relatively rare circumstances. A thread running after the end of main is not a good idea, and without formal synchronization with the end of the thread, preventing that is basically impossible.

There are two ways to do this with a detach() ed thread -- the _at_thread_exit methods of std::promise , or using OS-specific APIs.

A thread pool might be what you want.

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;
};

something vaguely like that.

Then make a 1 thread thread-pool, and shove tasks into that.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM