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.