PIP 5.6.1
Platform-Independent Primitives
Public Types | Public Member Functions | Static Public Member Functions | Protected Member Functions | List of all members
PIThread Class Reference

Thread object that executes work on a dedicated system thread. More...

#include <pithread.h>

Inheritance diagram for PIThread:
Inheritance graph
[legend]

Public Types

enum  Priority {
  piLowerst , piLow , piNormal , piHigh ,
  piHighest
}
 Thread priority hint. More...
 

Public Member Functions

 PIThread (void *data, ThreadFunc func, bool startNow=false, PISystemTime loop_delay={})
 Constructs a thread with user data, callback and optional immediate start.
 
 PIThread (std::function< void()> func, bool startNow=false, PISystemTime loop_delay={})
 Constructs a thread with a callback without custom data.
 
 PIThread (bool startNow=false, PISystemTime loop_delay={})
 Constructs a subclass-oriented thread with an optional loop delay.
 
virtual ~PIThread ()
 Destroys the thread object. If it is still running, destruction forces termination.
 
bool start ()
 Starts the thread with the stored callback and loop delay.
 
bool start (PISystemTime loop_delay)
 Stores a new loop delay and starts the thread.
 
bool start (ThreadFunc func)
 Stores a callback and starts the thread.
 
bool start (ThreadFunc func, PISystemTime loop_delay)
 Stores a callback and loop delay, then starts the thread.
 
bool start (std::function< void()> func)
 Stores a lambda callback and starts the thread.
 
bool start (std::function< void()> func, PISystemTime loop_delay)
 Stores a lambda callback and loop delay, then starts the thread.
 
bool startOnce ()
 Starts a one-shot thread without the repeating loop. More...
 
bool startOnce (ThreadFunc func)
 Stores a callback and starts one-shot execution. More...
 
bool startOnce (std::function< void()> func)
 Stores a lambda callback and starts one-shot execution.
 
bool stopAndWait (int timeout_ms) DEPRECATEDM("use stopAndWait(PISystemTime)")
 Deprecated overload of stopAndWait() that accepts milliseconds.
 
bool stopAndWait (PISystemTime timeout={})
 Requests stop and waits for thread completion. Returns false if the timeout expires.
 
void setData (void *d)
 Sets the data pointer passed to ThreadFunc callbacks.
 
void setSlot (ThreadFunc func)
 Sets the callback executed after each run() pass.
 
void setSlot (std::function< void()> func)
 Sets a lambda callback executed after each run() pass.
 
void setPriority (PIThread::Priority prior)
 Sets the priority hint. If the thread is already running, applies it immediately.
 
void * data () const
 Returns the data pointer passed to ThreadFunc callbacks.
 
PIThread::Priority priority () const
 Returns the configured priority hint.
 
bool isRunning () const
 Returns whether the thread is currently running.
 
bool isStopping () const
 Returns whether stop has been requested and the thread is still finishing.
 
bool waitForStart (PISystemTime timeout={})
 Waits until the thread starts. Returns false if the timeout expires first.
 
bool waitForStart (int timeout_msecs) DEPRECATEDM("use waitForStart(PISystemTime)")
 Deprecated overload of waitForStart() that accepts milliseconds. More...
 
bool waitForFinish (PISystemTime timeout={})
 Waits for thread completion. Returns false if the timeout expires first.
 
bool waitForFinish (int timeout_msecs) DEPRECATEDM("use waitForFinish(PISystemTime)")
 Deprecated overload of waitForFinish() that accepts milliseconds. More...
 
void needLockRun (bool need)
 Enables locking of the internal mutex around begin(), run(), callbacks and end().
 
PIMutexmutex () const
 Returns the internal mutex used by lock(), unlock() and needLockRun().
 
llong tid () const
 Returns the system thread identifier, or -1 when the thread is not running.
 
- Public Member Functions inherited from PIObject
 PIObject (const PIString &name=PIString())
 Constructs an object and initializes its name property.
 
virtual ~PIObject ()
 Destroys the object, raises deleted() and disconnects it from the event graph.
 
PIString name () const
 Returns the name property of this object.
 
virtual const char * className () const
 Returns the registered class name of this object.
 
virtual uint classNameID () const
 Returns the hash of className().
 
virtual const char * parentClassName () const
 Returns the registered parent class name, or an empty string for the root.
 
bool debug () const
 Returns whether piCoutObj output is enabled for this object.
 
void setName (const PIString &name)
 Sets the name property of this object.
 
void setDebug (bool debug)
 Enables or disables piCoutObj output for this object.
 
PIVariant property (const char *name) const
 Returns the property with name "name".
 
void setProperty (const char *name, const PIVariant &value)
 Sets the property "name" to "value" and creates it if needed. More...
 
bool isPropertyExists (const char *name) const
 Returns whether the property "name" exists.
 
void setThreadSafe (bool yes)
 Enables or disables the internal object mutex during handler execution. More...
 
bool isThreadSafe () const
 Returns whether the internal object mutex is enabled for handler execution.
 
bool execute (const PIString &method, const PIVector< PIVariantSimple > &vl)
 Executes a registered method or handler method by name with the supplied arguments. More...
 
bool execute (const PIString &method)
 Overload of execute() for a method without arguments.
 
bool execute (const PIString &method, const PIVariantSimple &v0)
 Overload of execute() for one argument.
 
bool execute (const PIString &method, const PIVariantSimple &v0, const PIVariantSimple &v1)
 Overload of execute() for two arguments.
 
bool execute (const PIString &method, const PIVariantSimple &v0, const PIVariantSimple &v1, const PIVariantSimple &v2)
 Overload of execute() for three arguments.
 
bool execute (const PIString &method, const PIVariantSimple &v0, const PIVariantSimple &v1, const PIVariantSimple &v2, const PIVariantSimple &v3)
 Overload of execute() for four arguments.
 
bool executeQueued (PIObject *performer, const PIString &method, const PIVector< PIVariantSimple > &vl)
 Queues execution of a registered method on the performer object. More...
 
bool executeQueued (PIObject *performer, const PIString &method)
 Overload of executeQueued() for a method without arguments.
 
bool executeQueued (PIObject *performer, const PIString &method, const PIVariantSimple &v0)
 Overload of executeQueued() for one argument.
 
bool executeQueued (PIObject *performer, const PIString &method, const PIVariantSimple &v0, const PIVariantSimple &v1)
 Overload of executeQueued() for two arguments.
 
bool executeQueued (PIObject *performer, const PIString &method, const PIVariantSimple &v0, const PIVariantSimple &v1, const PIVariantSimple &v2)
 Overload of executeQueued() for three arguments.
 
bool executeQueued (PIObject *performer, const PIString &method, const PIVariantSimple &v0, const PIVariantSimple &v1, const PIVariantSimple &v2, const PIVariantSimple &v3)
 Overload of executeQueued() for four arguments.
 
void dump (const PIString &line_prefix=PIString()) const
 Dumps object diagnostics to the project output stream.
 
PIStringList scopeList () const
 Returns the registered inheritance scope of this object, including its own class.
 
PIStringList methodsEH () const
 Returns full signatures of all registered event and handler methods for this class scope.
 
bool isMethodEHContains (const PIString &name) const
 Returns whether a registered event or handler method with this name exists.
 
PIString methodEHArguments (const PIString &name) const
 Returns the comma-separated argument type list of a registered method.
 
PIString methodEHFullFormat (const PIString &name) const
 Returns the full registered signature of a method.
 
PIString methodEHFromAddr (const void *addr) const
 Returns the registered method name for the specified entry-point address.
 
void piDisconnect (const PIString &sig, PIObject *dest, void *ev_h)
 Disconnects this source object from a specific destination handler for event "sig".
 
void piDisconnect (const PIString &sig, PIObject *dest)
 Disconnects this source object from all connections of event "sig" to destination object "dest".
 
void piDisconnect (const PIString &sig)
 Disconnects this source object from all connections of event "sig".
 
bool isPIObject () const
 Returns whether this pointer still refers to a live PIObject instance.
 
template<typename T >
bool isTypeOf () const
 Returns whether this object belongs to class "T" or one of its registered descendants.
 
template<typename T >
T * cast () const
 Returns this object cast to "T" when isTypeOf<T>() succeeds, otherwise nullptr.
 
void callQueuedEvents ()
 Executes all queued deliveries posted to this performer object.
 
bool maybeCallQueuedEvents ()
 Executes queued deliveries only when this object was used as a performer. More...
 
void deleteLater ()
 Schedules the object for deferred deletion. More...
 
void deleted (PIObject *o)
 Raised immediately before object destruction. More...
 

Static Public Member Functions

static void runOnce (PIObject *object, const char *handler, const PIString &name=PIString())
 Creates a temporary thread and invokes handler handler of object object on it. More...
 
static void runOnce (std::function< void()> func, const PIString &name=PIString())
 Creates a temporary thread and runs lambda expression func on it. More...
 
- Static Public Member Functions inherited from PIObject
static bool execute (PIObject *o, const PIString &method, const PIVector< PIVariantSimple > &vl)
 Static convenience wrapper for execute().
 
static bool execute (PIObject *o, const PIString &method)
 Static overload of execute() without arguments.
 
static bool execute (PIObject *o, const PIString &method, const PIVariantSimple &v0)
 Static overload of execute() for one argument.
 
static bool execute (PIObject *o, const PIString &method, const PIVariantSimple &v0, const PIVariantSimple &v1)
 Static overload of execute() for two arguments.
 
static bool execute (PIObject *o, const PIString &method, const PIVariantSimple &v0, const PIVariantSimple &v1, const PIVariantSimple &v2)
 Static overload of execute() for three arguments.
 
static bool execute (PIObject *o, const PIString &method, const PIVariantSimple &v0, const PIVariantSimple &v1, const PIVariantSimple &v2, const PIVariantSimple &v3)
 Static overload of execute() for four arguments.
 
static bool executeQueued (PIObject *o, PIObject *performer, const PIString &method, const PIVector< PIVariantSimple > &vl)
 Static convenience wrapper for executeQueued().
 
static bool executeQueued (PIObject *o, PIObject *performer, const PIString &method)
 Static overload of executeQueued() without arguments.
 
static bool executeQueued (PIObject *o, PIObject *performer, const PIString &method, const PIVariantSimple &v0)
 Static overload of executeQueued() for one argument.
 
static bool executeQueued (PIObject *o, PIObject *performer, const PIString &method, const PIVariantSimple &v0, const PIVariantSimple &v1)
 Static overload of executeQueued() for two arguments.
 
static bool executeQueued (PIObject *o, PIObject *performer, const PIString &method, const PIVariantSimple &v0, const PIVariantSimple &v1, const PIVariantSimple &v2)
 Static overload of executeQueued() for three arguments.
 
static bool executeQueued (PIObject *o, PIObject *performer, const PIString &method, const PIVariantSimple &v0, const PIVariantSimple &v1, const PIVariantSimple &v2, const PIVariantSimple &v3)
 Static overload of executeQueued() for four arguments.
 
static PIObject::Connection piConnect (PIObject *src, const PIString &sig, PIObject *dest_o, void *dest, void *ev_h, void *e_h, int args, const char *loc)
 Low-level direct connection helper behind the legacy CONNECT* macros.
 
static PIObject::Connection piConnectU (PIObject *src, const PIString &sig, PIObject *dest_o, void *dest, const PIString &hname, const char *loc, PIObject *performer=0)
 Low-level name-based connection helper behind CONNECTU() and CONNECTU_QUEUED().
 
static PIObject::Connection piConnectLS (PIObject *src, const PIString &sig, std::function< void()> *f, const char *loc)
 Low-level helper that connects an event to a lambda or functor wrapper.
 
static void piDisconnect (PIObject *src, const PIString &sig, PIObject *dest, void *ev_h)
 Disconnects source object "src" from a specific destination handler for event "sig".
 
static void piDisconnect (PIObject *src, const PIString &sig, PIObject *dest)
 Disconnects source object "src" from all connections of event "sig" to destination object "dest".
 
static void piDisconnect (PIObject *src, const PIString &sig)
 Disconnects source object "src" from all connections of event "sig".
 
static void raiseEvent (PIObject *sender, const uint eventID)
 Internal event delivery helper for registered events without arguments.
 
template<typename T0 >
static void raiseEvent (PIObject *sender, const uint eventID, const T0 &v0=T0())
 Internal event delivery helper for registered events with one argument.
 
template<typename T0 , typename T1 >
static void raiseEvent (PIObject *sender, const uint eventID, const T0 &v0=T0(), const T1 &v1=T1())
 Internal event delivery helper for registered events with two arguments.
 
template<typename T0 , typename T1 , typename T2 >
static void raiseEvent (PIObject *sender, const uint eventID, const T0 &v0=T0(), const T1 &v1=T1(), const T2 &v2=T2())
 Internal event delivery helper for registered events with three arguments.
 
template<typename T0 , typename T1 , typename T2 , typename T3 >
static void raiseEvent (PIObject *sender, const uint eventID, const T0 &v0=T0(), const T1 &v1=T1(), const T2 &v2=T2(), const T3 &v3=T3())
 Internal event delivery helper for registered events with four arguments.
 
static PIObjectfindByName (const PIString &name)
 Returns the first live object with name "name", or nullptr.
 
static bool isPIObject (const PIObject *o)
 Returns whether "o" points to a live PIObject instance.
 
static bool isPIObject (const void *o)
 Overload of isPIObject() for an untyped pointer.
 
template<typename T >
static bool isTypeOf (const PIObject *o)
 Returns whether "o" belongs to class "T" or one of its registered descendants.
 
template<typename T >
static bool isTypeOf (const void *o)
 Overload of isTypeOf() for an untyped pointer.
 
static PIString simplifyType (const char *a, bool readable=true)
 Simplifies a C++ type spelling for registered-method metadata.
 

Protected Member Functions

virtual void begin ()
 Virtual method executed once after the system thread starts and before started().
 
virtual void run ()
 Virtual method executed on each loop iteration until stop is requested.
 
virtual void end ()
 Virtual method executed once during thread shutdown after stopped().
 
- Protected Member Functions inherited from PIObject
PIObjectemitter () const
 Returns the source object that raised the current event. More...
 
virtual void propertyChanged (const char *name)
 Virtual method called after property "name" has been changed by setProperty().
 

Handlers

void stop ()
 Requests graceful thread shutdown. More...
 
void terminate ()
 Forces thread termination. Use only as a last resort. More...
 
void lock () const
 Locks the internal mutex.
 
void unlock () const
 Unlocks the internal mutex.
 

Events

void started ()
 Raised after the thread has started.
 
void stopped ()
 Raised when thread shutdown begins.
 

Additional Inherited Members

Detailed Description

Thread object that executes work on a dedicated system thread.

Thread class.

The default loop calls begin(), then repeats queued-delivery draining for this performer object plus run(), and finally calls end() when stopping. Use startOnce() when only one pass is needed and no repeated queued draining loop is required.

This class allow you exec your code in separate thread.

Synopsis

Multithreading allow you to execute code in several threads simultaneously. This trend allow you to use all cores of modern processors, but there are many dangers.

This class provide virtual functions begin(), run() and end(), which describes start, execution and finish work of some process. These functions executes in separate thread. When you execute start(int), PIThread create separate system thread and sequentially executes function begin(), run() and end(). You can reimplement each function and write your own code to execute.

Scheme of functions executing:

virtual begin()
event started()
while (isRunning()) { // while not stop()
virtual run()
ThreadFunc() // Slot or lambda
piMSleep(loop_delay) // if loop_delay > 0
}
event stopped()
virtual end()
bool isRunning() const
Returns whether the thread is currently running.
Definition: pithread.h:211
void started()
Raised after the thread has started.
virtual void begin()
Virtual method executed once after the system thread starts and before started().
Definition: pithread.h:309
virtual void run()
Virtual method executed on each loop iteration until stop is requested.
Definition: pithread.h:313
void stopped()
Raised when thread shutdown begins.
virtual void end()
Virtual method executed once during thread shutdown after stopped().
Definition: pithread.h:317
void piMSleep(double msecs)
Precise sleep for "msecs" milliseconds.
Definition: pitime.h:41
std::function< void(void *)> ThreadFunc
Callback executed by PIThread with the current data() pointer.
Definition: pithread.h:81

If no internal loop needed, you can use startOnce() method instead of start(int).

In this case scheme is next:

virtual begin()
event started()
virtual run()
ThreadFunc() // Slot or lambda
event stopped()
virtual end()

Unlike from directly using "pthread" or some similar you doesn`t need to write your own main thread cycle and sleep at every cycle end. PIThread make it for you, and your job is to set sleep value from contructor or when starting thread, and reimplement begin(), run() and end() functions.

Using with internal loop

class MyThread: public PIThread {
public:
void begin() override {piCout << "thread begin";}
void run() override {piCout << "thread run" << ++cnt;}
void end() override {piCout << "thread end";}
private:
int cnt = 0;
};
int main(int argc, char * argv[]) {
MyThread mt;
mt.start(100);
piMSleep(500);
mt.stop(true);
return 0;
}
// thread begin
// thread run 1
// thread run 2
// thread run 3
// thread run 4
// thread run 5
// thread end
#define PIOBJECT_SUBCLASS(name, parent)
Put this macro inside a PIObject subclass definition to inherit registered methods and class scope fr...
Definition: piobject_macros.h:53
Thread object that executes work on a dedicated system thread.
Definition: pithread.h:99
#define piCout
Definition: picout.h:36

Using without internal loop

class MyThread: public PIThread {
public:
void begin() override {piCout << "thread begin";}
void run() override {piCout << "thread run" << ++cnt;}
void end() override {piCout << "thread end";}
private:
int cnt = 0;
};
int main(int argc, char * argv[]) {
MyThread mt;
mt.startOnce();
piMSleep(500);
mt.stop(true);
return 0;
}
// thread begin
// thread run 1
// thread end

Using without subclassing

You can use PIThread without subclassing by using "ThreadFunc" pointer that can be set from constructor or by overloaded function start(ThreadFunc func, int loop_delay). If "func" if not null this function will be executed after run().

ThreadFunc is any static function with format "void func(void * data)", or lambda expression with format [...]( ){...}. "Data" is custom data set from constructor or with setData() function.

Also you can connect to event started(), but in this case you should to white your thread main cycle, because this event raised only one time after thread start.

Using with internal loop

void myThreadFunc(void * d) {
int * cnt = (int*)d;
piCout << "thread run" << ++(*cnt);
}
int main(int argc, char * argv[]) {
int cnt = 0;
mt.setData(&cnt);
mt.start(myThreadFunc, 100);
piMSleep(500);
mt.stop(true);
return 0;
}
// thread run 1
// thread run 2
// thread run 3
// thread run 4
// thread run 5
bool start()
Starts the thread with the stored callback and loop delay.
Definition: pithread.cpp:599
void setData(void *d)
Sets the data pointer passed to ThreadFunc callbacks.
Definition: pithread.h:185
void stop()
Requests graceful thread shutdown.
Definition: pithread.cpp:661

Using without internal loop

void myThreadFunc(void * d) {
int * cnt = (int*)d;
piCout << "thread run" << ++(*cnt);
}
int main(int argc, char * argv[]) {
int cnt = 0;
mt.setData(&cnt);
mt.startOnce(myThreadFunc);
piMSleep(500);
mt.stop(true);
return 0;
}
// thread run 1
bool startOnce()
Starts a one-shot thread without the repeating loop.
Definition: pithread.cpp:637

Using with lambda expression

int main(int argc, char * argv[]) {
int cnt = 0;
mt.start([&cnt](){
piCout << "thread run" << ++cnt;
}, 100);
piMSleep(500);
mt.stop(true);
return 0;
}
// thread run 1
// thread run 2
// thread run 3
// thread run 4
// thread run 5

Using with event

class MyObj: public PIObject {
PIOBJECT(MyObj)
public:
EVENT_HANDLER(void, threadRun) {
piForTimes (5) {
piCout << "threadRun" << ++cnt;
piMSleep(100);
}
};
private:
int cnt = 0;
};
int main(int argc, char * argv[]) {
MyObj mo;
CONNECTU(&mt, started, &mo, threadRun);
mt.startOnce();
mt.stop(true);
return 0;
}
// threadRun 1
// threadRun 2
// threadRun 3
// threadRun 4
// threadRun 5
Base class for objects that declare events, event handlers and registered methods.
Definition: piobject.h:56
#define CONNECTU(src, event, dest, handler)
Connect event "event" from object "src" to event handler or event "handler" of object "dest".
Definition: piobject_macros.h:204
#define EVENT_HANDLER
Synonym of EVENT_HANDLER0.
Definition: piobject_macros.h:91
#define PIOBJECT(name)
Put this macro inside a direct PIObject subclass definition to enable registered events,...
Definition: piobject_macros.h:46
#define piForTimes(c)
Macro for short replacement of standart "for".
Definition: picontainers.h:128

Locking

PIThread has inrternal mutex that can be locked and unlocked every run() if you set this flag with function needLockRun(true). Also you can access to this mutex by functions lock(), unlock() and mutex(). Using this functions outside of thread together with needLockRun(true) can defend your data.

Member Enumeration Documentation

◆ Priority

Thread priority hint.

Enumerator
piLowerst 

Lowest

piLow 

Low

piNormal 

Normal, this is default priority of threads and timers

piHigh 

High

piHighest 

Highest

Member Function Documentation

◆ startOnce() [1/2]

bool PIThread::startOnce ( )

Starts a one-shot thread without the repeating loop.

Start execution of run() once. Thread also exec external function set by setSlot() if its not null. \return \c false if thread already started or cant start thread

◆ startOnce() [2/2]

bool PIThread::startOnce ( ThreadFunc  func)

Stores a callback and starts one-shot execution.

Overloaded function. Set external function "func" before start.

Returns
false if thread already started or can`t start thread

◆ waitForStart()

bool PIThread::waitForStart ( int  timeout_msecs = -1)
inline

Deprecated overload of waitForStart() that accepts milliseconds.

Block until thread start within "timeout_msecs" or forever if "timeout_msecs" < 0

Returns
true if thread started less than timeout
false if timeout is exceeded

◆ waitForFinish()

bool PIThread::waitForFinish ( int  timeout_msecs = -1)
inline

Deprecated overload of waitForFinish() that accepts milliseconds.

Block until thread finish for "timeout_msecs" or forever if "timeout_msecs" < 0

Returns
true if thread finished less than timeout
false if timeout is exceeded

◆ runOnce() [1/2]

void PIThread::runOnce ( PIObject object,
const char *  handler,
const PIString name = PIString() 
)
static

Creates a temporary thread and invokes handler handler of object object on it.

This method create PIThread with name "name" and execute event handler "handler" of object "object" in this thread.
This PIThread automatically delete on function finish.

class MyObj: public PIObject {
PIOBJECT(MyObj)
public:
EVENT_HANDLER(void, threadRun) {
piForTimes (5) {
piCout << "threadRun";
piMSleep(100);
}
};
};
int main(int argc, char * argv[]) {
MyObj mo;
PIThread::runOnce(&mo, "threadRun");
piMSleep(1000); // wait for thread finish
return 0;
}
static void runOnce(PIObject *object, const char *handler, const PIString &name=PIString())
Creates a temporary thread and invokes handler handler of object object on it.
Definition: pithread.cpp:1005

◆ runOnce() [2/2]

void PIThread::runOnce ( std::function< void()>  func,
const PIString name = PIString() 
)
static

Creates a temporary thread and runs lambda expression func on it.

This method create PIThread with name "name" and execute lambda expression "func" in this thread.
This PIThread automatically delete on function finish.
"func" shouldn`t have arguments.

piCout << "thread func";
piMSleep(100);
}
});
piMSleep(1000);

◆ stop()

void PIThread::stop ( )

Requests graceful thread shutdown.

Mark thread to stop execution and wait for finish if "wait" is true. Thread can be stopped only outside of run() or external method.

Warning
This function can block for infinite time if "wait" is true and any of thread function is busy forever.

◆ terminate()

void PIThread::terminate ( )

Forces thread termination. Use only as a last resort.

Stop execution of thread immediately.

Warning
Memory can be corrupted, try not to use this method!