92 lines
3.1 KiB
C
92 lines
3.1 KiB
C
|
#pragma once
|
||
|
|
||
|
#include "mutex.h"
|
||
|
#include <iostream>
|
||
|
|
||
|
#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 <cgv/config/lib_end.h>
|