Libthreadar 1.6.0
Classes | Public Member Functions | Protected Member Functions | List of all members
libthreadar::thread Class Referenceabstract

Class thread is a pure virtual class, that implements thread creation and operations. More...

#include <thread.hpp>

Inherited by libthreadar::thread_signal.

Classes

class  cancel_except
 exception used to trigger thread cancellation More...
 

Public Member Functions

 thread ()
 constructor
 
 thread (const thread &ref)=delete
 copy constructor and assignment operator are disabled
 
 thread (thread &&ref) noexcept=default
 
threadoperator= (const thread &ref)=delete
 
threadoperator= (thread &&ref) noexcept=default
 
virtual ~thread ()
 destructor
 
void reset_stack_size ()
 reset the stack size to the system default value More...
 
void set_stack_size (unsigned int val)
 set the stack size to non default value More...
 
unsigned int get_stack_size () const
 get the current stack size value More...
 
virtual void set_signal_mask (const sigset_t &mask)
 set signal mask of the thread spawn by run() More...
 
void run ()
 launch the current object routing in a separated thread
 
bool is_running () const
 checks whether a separated thread is running the inherited_run() method of this object More...
 
bool is_running (pthread_t &id) const
 checks whether the object is running in a separated thread More...
 
void join () const
 the caller will be suspended until the current object's thread ends
 
void kill () const
 
void cancel ()
 the caller send a cancellation request to this object's running thread if any More...
 

Protected Member Functions

virtual void inherited_run ()=0
 action to be performed in the separated thread (implementation is expected in inherited classes) More...
 
void cancellation_checkpoint () const
 available withing the inherited_run() method to eventually trigger thread cancellation More...
 
virtual void inherited_cancel ()
 

Detailed Description

Class thread is a pure virtual class, that implements thread creation and operations.

At the difference of the C++11 thread directive, the creation of an inherited class object does not immediately launch a thread. The inherited class can first provide any fields necessary to the thread execution by mean of inherited class constructor or better by using several customized method of the inherited class, which brings better readability and ease code maintenance than having a call with a lot of argument as C++11 thread managment requests it to be done.

Inherited classes must only define the inherited_run() method, method that will be run in its specific thread once the run() method will be called on that object. The private fields of inherited classes can be used to host variables only accessible by the running thread. Inherited class may also implement method to communicate with the running thread, here too the private (or protected) fields of the class can be used to host mutex if one is necessary to provide consistent information from the current thread to the other interacting with it by mean of adhoc methods of the inherited class.

The join() method can be used by the run() caller to wait for thread termination. If the corresponding thread has already ended, the join() method ends immediately. If the thread aborted due to an exception, this exception will be rethrown from the the thread calling join(). Last, calling join() on an object which thread has not yet started or which has ended and for which join() has already been run, does nothing: the join() method returns immediately.

Note
the thread object destructor kills the thread if it was running, this could have generated an exception thrown from inherited_run() in another context, but here (thread class destructor), all are caught and ignored. Under some operating systems (Cygwin), if a pthread has already started but has not yet reached the time it has called the inherited_run() method when object destructor is called, then, when the subthread calls the inherited_run() method, the system may report a SEGFAULT in particular when the fields of the object that are from the inherited class do not exist anymore. The kill() and join() present in the thread::~thread destructor, cannot prevent this because when the execution pointer reaches them, all inherited class fields do no more exist anyway.
Important!
IT IS THUS IMPORTANT FOR ANY INHERITED CLASS TO INVOKE cancel() [or other mechanism to stop the thread] and THEN join() IN THEIR DESTRUCTOR

Once the thread is no more running, a new call to run() is allowed but only if a join() call has been issued since the thread was last run. This allows to run again a thread without having to pass again all the possibly many arguments and datastructures requested by this thread.

Examples
/doc/examples/fast_tampon_example.cpp, and /doc/examples/thread_example.cpp.

Definition at line 101 of file thread.hpp.

Member Function Documentation

◆ cancel()

void libthreadar::thread::cancel ( )

the caller send a cancellation request to this object's running thread if any

Note
the thread will effectively end if it runs its cancellation_checkpoint() regularly in its loop(s), see below. As an alternative, the inherited class can rely in the protected method inherited_cancel() to implement a mechanism to stop the possibly running thread.

◆ cancellation_checkpoint()

void libthreadar::thread::cancellation_checkpoint ( ) const
protected

available withing the inherited_run() method to eventually trigger thread cancellation

Note
since release 1.5.0 the kill() method has been renamed as cancel() and does no more rely on pthread_cancel() which does not work well under C++ context since the NPTL implementation used under Linux. The cancellation point are thus defined manually by cancellation_checkpoint() which has to be called regularly in the implementation of your threads (see inherited_run()), if you want to be able to call the cancel() method to stop the thread properly. Thread cancellation relies on the libhtreadar::thread::cancel_except exception that should never be caught in your code, either by cathing explicitely other exceptions or by preventing it to be catch by a cath-all statement:
   void inherited_run()
   {
       try
       {
           while(something)
           {
              ... // code to protect
              cancellation_checkpoint();
           }
       }
       catch(cancel_except &)
       {
           // eventually release some resource
           // but propagate the exception!
           throw;
       }
       catch(...)
       {
        // a catch-all statement you want/need
           // not rethrowing the exception
       }
   }
Of course if the catch-all statement do rethrow all exceptions nothing special is to be done as the cancel_except exception will still be propagated upward and drive the thread cancellation to its end.

◆ get_stack_size()

unsigned int libthreadar::thread::get_stack_size ( ) const
inline

get the current stack size value

Returns
zero when a system default stack is used, else the argument that has been provided to set_stack_size() method.

Definition at line 134 of file thread.hpp.

◆ inherited_cancel()

virtual void libthreadar::thread::inherited_cancel ( )
inlineprotectedvirtual

this method is called by cancel() even if the thread is not running() to let inherited classes define alternative method to stop the thread running inherited_run() than the cancellation_checkpoint() mechanism, or in complement to it. Attention should be taken to the fact the caller of cancel() is not likely to be the same thread as the one running inherited_run(), and mutex or other mechanism may be necessary to avoid concurrent access to some fields in your inherited classes, fields used to communicate the cancellation requested to the thread from the other thread calling cancel().

Definition at line 251 of file thread.hpp.

◆ inherited_run()

virtual void libthreadar::thread::inherited_run ( )
protectedpure virtual

action to be performed in the separated thread (implementation is expected in inherited classes)

Note
There is no argument to provide, because this is the responsibility of the inherited class to defined private/protected fields, methods and/or constructors to set their value. It is also the responsibility of the inherited class to define if a (private or protected) field is to be exclusively accessed from the thread running inherited_run() or by the thread calling this objects or by both (if for example the field is a mutex) to provide communication mean with the thread running the inherited_run() method.
Examples
/doc/examples/fast_tampon_example.cpp, and /doc/examples/thread_example.cpp.

◆ is_running() [1/2]

bool libthreadar::thread::is_running ( ) const
inline

checks whether a separated thread is running the inherited_run() method of this object

Examples
/doc/examples/fast_tampon_example.cpp, and /doc/examples/thread_example.cpp.

Definition at line 146 of file thread.hpp.

◆ is_running() [2/2]

bool libthreadar::thread::is_running ( pthread_t &  id) const

checks whether the object is running in a separated thread

Parameters
[out]idreturns the thread_id upon success
Returns
true if the object is running under a separated thread if false is returned, the argument is not set

◆ kill()

void libthreadar::thread::kill ( ) const
Deprecated:
WARNING! kill() is DEPRECATED since release 1.5.0 and will be removed in the future as it does not work for some glibc implementations when using C++ code (collides with exceptions). USE cancel() feature instead. See documentation about cancel() this is not a 1:1 replacement of kill(). See also inherited_cancel(), and cancellation_checkpoint() methods.
Examples
/doc/examples/thread_example.cpp.

◆ reset_stack_size()

void libthreadar::thread::reset_stack_size ( )

reset the stack size to the system default value

this method must not be called when the current object has its thread running.

Note
this sets back the stack to the system default

◆ set_signal_mask()

virtual void libthreadar::thread::set_signal_mask ( const sigset_t &  mask)
inlinevirtual

set signal mask of the thread spawn by run()

this value persists accros several run()/join() executions.

Note
see sigsetops(3) for details on manipulating signal sets

Reimplemented in libthreadar::thread_signal.

Definition at line 140 of file thread.hpp.

◆ set_stack_size()

void libthreadar::thread::set_stack_size ( unsigned int  val)

set the stack size to non default value

this method must not be called when the current object has its thread running.

Parameters
[in]valsize in bytes of the stack to allocate and use.

The documentation for this class was generated from the following file: