#pragma once #include "mutex.h" #include #include "lib_begin.h" namespace cgv { namespace os { /// type used to identify a thread typedef unsigned long long thread_id_type; /** Thread class implementation that uses pthreads internally. To create and run your own thread, follow this example: \begincode class mythread : thread { void run() { //no external stop request? while(no_stop_request()) { std::cout << "abc" << std::endl; } } }; mythread t1; t1.start(); ... t1.stop(); \endcode */ class CGV_API thread { protected: void *pthread; bool stop_request; bool running; bool delete_after_termination; static void* execute_s(void* args); /// executes the run method void execute(); public: ///create the thread thread(); /// standard destructor (a running thread will be killed) virtual ~thread(); /// start the implemented run() method (asynchronly) and destruct the thread object void start(bool _delete_after_termination = false); /// thread function to override virtual void run()=0; /// sleep till the signal from the given condition_mutex is sent, lock the mutex first and unlock after waiting static void wait_for_signal(condition_mutex& cm); /// prefered approach to wait for signal and implemented as { cm.lock(); wait_for_signal(cm); cm.unlock(); } static void wait_for_signal_with_lock(condition_mutex& cm); /// sleep till the signal from the given condition_mutex is sent or the timeout is reached, lock the mutex first and unlock after waiting static bool wait_for_signal_or_timeout(condition_mutex& cm, unsigned millisec); /// prefered approach to wait for signal or the timeout is reached and implemented as { cm.lock(); wait_for_signal_or_timeout(cm,millisec); cm.unlock(); } static bool wait_for_signal_or_timeout_with_lock(condition_mutex& cm, unsigned millisec); /// wait the given number of milliseconds static void wait(unsigned millisec); /// try to stop the thread execution via indicating a stop request. The existence of a stop request /// can be recognized by the no_stop_request() method. This test should be done periodically within /// the implementation of the run() method, e.g. to leave the execution loop in a clean way. void stop(); /// kill a running thread void kill(); /** the thread is interpreted as a slave thread and started from another master thread. This method is called from the master thread in order to wait for termination of the slave thread. */ void wait_for_completion(); ///return true if thread is running inline bool is_running() { return running; } /// check if there is a stop request inline bool have_stop_request() { return stop_request; } /// return the id of the currently executed thread static thread_id_type get_current_thread_id(); /// return id of this thread thread_id_type get_id() const; }; /// start a function in a newly constructed thread extern CGV_API thread* start_in_thread(void (*func)(thread_id_type), bool _delete_after_termination = false); } } #include