Possible Duplicate:
C++0x thread interruption
I am trying to kill/stop a c++ std::thread by using its thread object.
How can we do this?
Possible Duplicate:
C++0x thread interruption
I am trying to kill/stop a c++ std::thread by using its thread object.
How can we do this?
@bamboon's answer is good, however I feel this deserves a stronger statement.
Whatever the language you use, your program will acquire and release resources: memory, file descriptors, ... For simple programs that are fired in one shots, leaking resources does not matter much: when the program ends modern OSes automatically take the resources back; however for long-running programs a basic requirement is not to leak resources, or at least not repetitively.
Therefore, you should have been taught from the beginning that when you acquire a resource you will have to ensure it is released at one point:
void foo(int i) { int* array = malloc(sizeof(int) * i); /* do something */ free(array); } So, ask yourself the question:
Well, as we said, when a program ends the OS gathers the resources back, so assuming (and this is some assumption) that you did not acquire a resource on another system OR that this system is well protected against such abuse, no harm, no foul.
However, when you kill a thread, the program still runs, thus the OS does not gather the resources back. You leaked memory, you locked a file for writing that you cannot unlock any longer, ... You shall not kill threads.
Higher level languages have a way to handle this: exceptions. Because programs should be exception safe anyway, Java (for example) will kill a thread by pausing it, throwing an exception at the point of execution, and gently unwind the stack. However there is no such facility in C++, yet.
Is it impossible ? No, obviously not. Actually, you could perfectly reuse the very same idea:
std::thread, interruptible_thread class will also contain an interrupt flagstd::thread when launching it, and store it in a thread-local wayThat is:
// Synopsis class interrupt_thread_exception; class interruptible_thread; void check_for_interrupt(); // Interrupt exception class interrupt_thread_exception: public virtual std::exception { public: virtual char const* what() const override { return "interrupt"; } }; // class interrupt_thread_exception // Interruptible thread class interruptible_thread { public: friend void check_for_interrupt(); template <typename Function, typename... Args> interruptible_thread(Function&& fun, Args&&... args): _thread([](std::atomic_bool& f, Function&& fun, Args&&... args) { _flag_ref = &f; fun(std::forward<Args>(args)...); }, _flag, std::forward<Function>(fun), std::forward<Args>(args)...) {} bool stopping() const { return _flag.load(); } void stop() { _flag.store(true); } private: static thread_local std::atomic_bool* _flag_ref = nullptr; std::atomic_bool _flag = false; std::thread _thread; }; // class interruptible_thread // Interruption checker inline void check_for_interrupt() noexcept(false) { if (not interruptible_thread::_flag_ref) { return; } if (not interruptible_thread::_flag_ref->load()) { return; } throw interrupt_thread_exception(); } // check_for_interrupt Now you can just sprinkle your threaded code with checks for interrupt at appropriate places.
void foo(int) is already not exception safe, if you have an interruption check in the middle of `/* do something */' it will still be wrong.try/catch blocks, RAII, etc... whereas brutal interruption leaves you not tool to clean up. Note that I said checks for interrupt at appropriate places.! And you can still interrupt foo, as long as you catch the exception so that free is executed... but it was not really meant like that, I was more showing off the need for cleanup explicitly while a well built C++ program would use RAII, obviously.terminate() feature uses a broadly similar approach. Their terminology: "interruption points". An advantage of boost::thread over the code above: boost::thread also has built-in support for interruption of sleeping operations. E.g. of boost::thread::sleep_for().You can't.
std::threads are not interruptible. You can use boost::thread which offers this feature.
Boost does this by defining "interrupt points" on which the thread will end if it is interrupted and reaches such a point.
Nevertheless, most of the time thinking about a redesign might be the cleanest and easiest way to reach what you are trying to achieve.
If you are still looking for a C++11 implementation of interruptible threads checkout out Anthony Williams (owner of boost thread) book "C++ Concurrency in Action". He goes through a basic implementation of how such a thing can be achieved.
std::thread::native_handle gives you access to the platform specific underlying thread handle which might support interrupting, however this approach makes your code unportable and probably not cleaner in any way.