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

Thread class. More...

#include <pithread.h>

Inheritance diagram for PIThread:
Inheritance graph
[legend]

Public Types

enum  Priority {
  piLowerst , piLow , piNormal , piHigh ,
  piHighest
}
 Priority of thread. More...
 

Public Member Functions

 PIThread (void *data, ThreadFunc func, bool startNow=false, PISystemTime loop_delay={})
 Contructs thread with custom data "data", external function "func" and main loop delay "loop_delay".
 
 PIThread (std::function< void()> func, bool startNow=false, PISystemTime loop_delay={})
 Contructs thread with external function "func" and main loop delay "loop_delay".
 
 PIThread (bool startNow=false, PISystemTime loop_delay={})
 Contructs thread with main loop delay "loop_delay".
 
bool start ()
 Start thread.
 
bool start (PISystemTime loop_delay)
 Start thread.
 
bool start (ThreadFunc func)
 Start thread.
 
bool start (ThreadFunc func, PISystemTime loop_delay)
 Start thread.
 
bool start (std::function< void()> func)
 Start thread.
 
bool start (std::function< void()> func, PISystemTime loop_delay)
 Start thread.
 
bool startOnce ()
 Start thread without internal loop. More...
 
bool startOnce (ThreadFunc func)
 Start thread without internal loop. More...
 
bool startOnce (std::function< void()> func)
 Start thread without internal loop.
 
bool stopAndWait (PISystemTime timeout={})
 Stop thread and wait for finish. Returns false if timeout expired.
 
void setData (void *d)
 Set common data passed to external function.
 
void setSlot (ThreadFunc func)
 Set external function that will be executed after every run()
 
void setSlot (std::function< void()> func)
 Set external function that will be executed after every run()
 
void setPriority (PIThread::Priority prior)
 Set thread priority.
 
void * data () const
 Returns common data passed to external function.
 
PIThread::Priority priority () const
 Return thread priority.
 
bool isRunning () const
 Return if thread is running.
 
bool isStopping () const
 Return if thread is stopping.
 
bool waitForStart (PISystemTime timeout={})
 Wait for thread start.
 
bool waitForStart (int timeout_msecs) DEPRECATEDM("use waitForStart(PISystemTime)")
 
bool waitForFinish (PISystemTime timeout={})
 Wait for thread finish. Returns false if timeout expired.
 
bool waitForFinish (int timeout_msecs) DEPRECATEDM("use waitForFinish(PISystemTime)")
 
void needLockRun (bool need)
 Set necessity of lock every run() with internal mutex.
 
PIMutexmutex () const
 Returns internal mutex.
 
llong tid () const
 Returns thread ID.
 
- Public Member Functions inherited from PIObject
 PIObject (const PIString &name=PIString())
 Contructs PIObject with name "name".
 
PIString name () const
 Returns object name.
 
virtual const char * className () const
 Returns object class name.
 
virtual const char * parentClassName () const
 Returns parent class name.
 
bool debug () const
 Return if piCoutObj of this object is active.
 
void setName (const PIString &name)
 Set object name.
 
void setDebug (bool debug)
 Set object piCoutObj active.
 
PIVariant property (const char *name) const
 Returns property with name "name".
 
void setProperty (const char *name, const PIVariant &value)
 Set property with name "name" to "value". If there is no such property in object it will be added.
 
bool isPropertyExists (const char *name) const
 Returns if property with name "name" exists.
 
PIStringList scopeList () const
 Returns subclass scope of this object (including this class name)
 
void piDisconnect (const PIString &sig, PIObject *dest, void *ev_h)
 Disconnect object from all connections with event name "sig", connected to destination object "dest" and handler "ev_h".
 
void piDisconnect (const PIString &sig, PIObject *dest)
 Disconnect object from all connections with event name "sig", connected to destination object "dest".
 
void piDisconnect (const PIString &sig)
 Disconnect object from all connections with event name "sig".
 
bool isPIObject () const
 Returns if this is valid PIObject (check signature)
 
template<typename T >
bool isTypeOf () const
 Returns if this is valid PIObject subclass "T" (check signature and classname)
 
template<typename T >
T * cast () const
 Returns cast to T if this is valid subclass "T" (check by isTypeOf()) or "nullptr".
 
void callQueuedEvents ()
 Execute all posted events from CONNECTU_QUEUED connections.
 
bool maybeCallQueuedEvents ()
 Check if any CONNECTU_QUEUED connections to this object and execute them. More...
 
void deleteLater ()
 Mark object to delete. More...
 
void deleted (PIObject *o)
 Raise before object delete. More...
 

Static Public Member Functions

static void runOnce (PIObject *object, const char *handler, const PIString &name=PIString())
 Call event handler "handler" of object "object" in separate thread. More...
 
static void runOnce (std::function< void()> func, const PIString &name=PIString())
 Call lambda expression "func" in separate thread. More...
 
- Static Public Member Functions inherited from PIObject
static void piDisconnect (PIObject *src, const PIString &sig, PIObject *dest, void *ev_h)
 Disconnect object "src" from all connections with event name "sig", connected to destination object "dest" and handler "ev_h".
 
static void piDisconnect (PIObject *src, const PIString &sig, PIObject *dest)
 Disconnect object "src" from all connections with event name "sig", connected to destination object "dest".
 
static void piDisconnect (PIObject *src, const PIString &sig)
 Disconnect object "src" from all connections with event name "sig".
 
static PIObjectfindByName (const PIString &name)
 Returns PIObject* with name "name" or 0, if there is no object found.
 
static bool isPIObject (const PIObject *o)
 Returns if "o" is valid PIObject (check signature)
 
template<typename T >
static bool isTypeOf (const PIObject *o)
 Returns if "o" is valid PIObject subclass "T" (check signature and classname)
 

Protected Member Functions

virtual void begin ()
 Function executed once at the start of thread.
 
virtual void run ()
 Function executed at every "loop_delay" msecs until thread was stopped.
 
virtual void end ()
 Function executed once at the end of thread.
 
- Protected Member Functions inherited from PIObject
PIObjectemitter () const
 Returns PIObject* which has raised an event. This value is correct only in definition of some event handler.
 
virtual void propertyChanged (const char *name)
 Virtual function executes after property with name "name" has been changed.
 

Handlers

void stop ()
 Stop thread. More...
 
void terminate ()
 Strongly stop thread. More...
 
void lock () const
 Lock internal mutex.
 
void unlock () const
 Unlock internal mutex.
 

Events

void started ()
 Raise on thread start.
 
void stopped ()
 Raise on thread stop.
 

Additional Inherited Members

Detailed Description

Thread class.

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
Return if thread is running.
Definition: pithread.h:183
void started()
Raise on thread start.
virtual void begin()
Function executed once at the start of thread.
Definition: pithread.h:276
virtual void run()
Function executed at every "loop_delay" msecs until thread was stopped.
Definition: pithread.h:280
void stopped()
Raise on thread stop.
virtual void end()
Function executed once at the end of thread.
Definition: pithread.h:284
void piMSleep(double msecs)
Precise sleep for "msecs" milliseconds.
Definition: pitime.h:42

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)
You should use this macro after class declaration to use EVENT and EVENT_HANDLER of parent class,...
Definition: piobject_macros.h:44
Thread class.
Definition: pithread.h:72
#define piCout
Macro used for conditional (piDebug) output to PICout(StdOut)
Definition: picout.h:35

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()
Start thread.
Definition: pithread.cpp:599
void setData(void *d)
Set common data passed to external function.
Definition: pithread.h:157
void stop()
Stop thread.
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()
Start thread without internal 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
This is base class for any classes which use events -> handlers mechanism.
Definition: piobject.h:41
#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:184
#define EVENT_HANDLER
Synonym of EVENT_HANDLER0.
Definition: piobject_macros.h:83
#define PIOBJECT(name)
You should use this macro after class declaration to use EVENT and EVENT_HANDLER and correct piCoutOb...
Definition: piobject_macros.h:38
#define piForTimes(c)
Macro for short replacement of standart "for".
Definition: picontainers.h:134

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

Priority of thread.

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 ( )

Start thread without internal 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)

Start thread without internal loop.

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

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

◆ stop()

void PIThread::stop ( )

Stop thread.

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 ( )

Strongly stop thread.

Stop execution of thread immediately.

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

◆ waitForStart()

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

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

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

Call event handler "handler" of object "object" in separate thread.

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())
Call event handler "handler" of object "object" in separate thread.
Definition: pithread.cpp:1005

◆ runOnce() [2/2]

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

Call lambda expression "func" in separate thread.

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);