# PIP: PIThread Class Reference

PIThread Class Reference

Thread class. More...

Inheritance diagram for PIThread:
[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, int loop_delay=-1)
| Contructs thread with custom data "data", external function "func" and main loop delay "loop_delay".
| PIThread (bool startNow=false, int loop_delay=-1)
| Contructs thread with main loop delay "loop_delay".
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 | setPriority (PIThread::Priority prior)
| Set priority of thread.
void * | data () const
| Returns common data passed to external function.
PIThread::Priority | priority () const
| Return priority of thread.
bool | isRunning () const
| Return `true` if thread is running.
void | needLockRun (bool need)
| Set necessity of lock every run with internal mutex.
PIMutex & | mutex ()
| Return internal mutex.
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 * | superClassName () const
| Returns object superclass name.
bool | debug () const
| Return if debug of this object is active.
void | setName (const PIString &name)
| Set object name.
void | setDebug (bool debug)
| Set object debug active.
const PIMap< PIString, PIVariant > & | properties () const
| Returns properties of the object.
int | propertiesCount () const
| Returns properties count of the object.
PIVariant | property (const PIString &name) const
| Returns property with name "name".
void | setProperty (const PIString &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 PIString &name) const
| Returns if property with name "name" exists.

## Protected Member Functions

virtual void | begin ()
| Function executed once at the start of thread.
virtual void | run ()
| Function executed at every "timer_delay" msecs until thread was stopped.
virtual void | end ()
| Function executed once at the end of thread.
Protected Member Functions inherited from PIObject
PIObject * | emitter () const
| Returns PIObject* which has raised an event. This value is correct only in definition of some event handler.
virtual void | propertyChanged (const PIString &name)
| Virtual function executes after property with name "name" has been changed.
void | deleted ()
| Raise before object delete. More...

## Handlers

bool | start (int timer_delay)
| Start thread. More...
bool | start (ThreadFunc func, int timer_delay)
| Start thread. More...
bool | startOnce ()
| Start thread without internal loop. More...
bool | startOnce (ThreadFunc func)
| Start thread without internal loop. More...
void | stop (bool wait)
| Stop thread. More...
void | terminate ()
| Strongly stop thread. More...
bool | waitForStart (int timeout_msecs)
| Wait for thread start. More...
bool | waitForFinish (int timeout_msecs)
| Wait for thread finish. More...
void | lock ()
| Lock internal mutex.
void | unlock ()
| Unlock internal mutex.

## Events

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

## Additional Inherited Members

Static Public Member Functions inherited from PIObject
static void | piDisconnect (PIObject *src, const PIString &sig)
| Disconnect object "src" from all connections with event name "sig".
static void | piDisconnect (PIObject *src)
| Disconnect object "src" from all connections, i.e. all connections where object "src" is emitter.
static PIObject * | findByName (const PIString &name)
| Returns PIObject* with name "name" or 0, if there is no object found.
Related Functions inherited from PIObject
#define | piCoutObj
| Macro used for conditional (piDebug and PIObject::debug()) output to PICout for subclasses of PIObject.
#define | PIOBJECT(name)
| you should use this macro after class declaration to use EVENT and EVENT_HANDLER and correct piCoutObj output
#define | PIOBJECT_SUBCLASS(name, parent)
| you should use this macro after class declaration to use EVENT and EVENT_HANDLER of parent class
#define | EVENT_HANDLER0(ret, name) ret name()
| declare event handler "event" with name "name" and return type "ret", ret name()
#define | EVENT_HANDLER1(ret, name, type0, var0) ret name(type0 var0)
| declare event handler "event" with name "name" and return type "ret", ret name(type0 var0)
#define | EVENT_HANDLER2(ret, name, type0, var0, type1, var1) ret name(type0 var0, type1 var1)
| declare event handler "event" with name "name" and return type "ret", ret name(type0 var0, type1 var1)
#define | EVENT_HANDLER3(ret, name, type0, var0, type1, var1, type2, var2) ret name(type0 var0, type1 var1, type2 var2)
| declare event handler "event" with name "name" and return type "ret", ret name(type0 var0, type1 var1, type2 var2)
#define | EVENT_HANDLER4(ret, name, type0, var0, type1, var1, type2, var2, type3, var3) ret name(type0 var0, type1 var1, type2 var2, type3 var3)
| declare event handler "event" with name "name" and return type "ret", ret name(type0 var0, type1 var1, type2 var2, type3 var3)
#define | EVENT_HANDLER EVENT_HANDLER0
| EVENT_HANDLER is synonym of EVENT_HANDLER0.
#define | EVENT_VHANDLER0(ret, name) virtual ret name()
| declare virtual event handler "event" with name "name" and return type "ret", virtual ret name()
#define | EVENT_VHANDLER1(ret, name, type0, var0) virtual ret name(type0 var0)
| declare virtual event handler "event" with name "name" and return type "ret", virtual ret name(type0 var0)
#define | EVENT_VHANDLER2(ret, name, type0, var0, type1, var1) virtual ret name(type0 var0, type1 var1)
| declare virtual event handler "event" with name "name" and return type "ret", virtual ret name(type0 var0, type1 var1)
#define | EVENT_VHANDLER3(ret, name, type0, var0, type1, var1, type2, var2) virtual ret name(type0 var0, type1 var1, type2 var2)
| declare virtual event handler "event" with name "name" and return type "ret", virtual ret name(type0 var0, type1 var1, type2 var2)
#define | EVENT_VHANDLER4(ret, name, type0, var0, type1, var1, type2, var2, type3, var3) virtual ret name(type0 var0, type1 var1, type2 var2, type3 var3)
| declare virtual event handler "event" with name "name" and return type "ret", virtual ret name(type0 var0, type1 var1, type2 var2, type3 var3)
#define | EVENT_VHANDLER EVENT_VHANDLER0
| EVENT_VHANDLER is synonym of EVENT_VHANDLER0.
#define | EVENT0(name) void name();
| declare event "event" with name "name", void name();
#define | EVENT1(name, type0, var0) void name(type0 var0);
| declare event "event" with name "name", void name(type0 var0);
#define | EVENT2(name, type0, var0, type1, var1) void name(type0 var0, type1 var1);
| declare event "event" with name "name", void name(type0 var0, type1 var1);
#define | EVENT3(name, type0, var0, type1, var1, type2, var2) void name(type0 var0, type1 var1, type2 var2);
| declare event "event" with name "name", void name(type0 var0, type1 var1, type2 var2);
#define | EVENT4(name, type0, var0, type1, var1, type2, var2, type3, var3) void name(type0 var0, type1 var1, type2 var2, type3 var3);
| declare event "event" with name "name", void name(type0 var0, type1 var1, type2 var2, type3 var3);
#define | EVENT EVENT0
| EVENT is synonym of EVENT0.
#define | CONNECTU(src, event, dest, handler)
| connect event "event" from object "src" to event handler "handler". "Event" and "handler" must has equal argument lists.
#define | CONNECT0(ret, src, event, dest, handler)
| connect event "event" from object "src" to event handler "handler" with return type "ret" from object "dest" with check of event and handler exists
#define | CONNECT1(ret, type0, src, event, dest, handler)
| connect event "event" from object "src" to event handler "handler" with return type "ret" from object "dest" with check of event and handler exists
#define | CONNECT2(ret, type0, type1, src, event, dest, handler)
| connect event "event" from object "src" to event handler "handler" with return type "ret" from object "dest" with check of event and handler exists
#define | CONNECT3(ret, type0, type1, type2, src, event, dest, handler)
| connect event "event" from object "src" to event handler "handler" with return type "ret" from object "dest" with check of event and handler exists
#define | CONNECT4(ret, type0, type1, type2, type3, src, event, dest, handler)
| connect event "event" from object "src" to event handler "handler" with return type "ret" from object "dest" with check of event and handler exists
#define | CONNECT CONNECT0
| CONNECT is synonym of CONNECT0.
#define | WEAK_CONNECT0(ret, src, event, dest, handler)
| connect event "event" from object "src" to event handler "handler" with return type "ret" from object "dest" without check of event exists
#define | WEAK_CONNECT1(ret, type0, src, event, dest, handler)
| connect event "event" from object "src" to event handler "handler" with return type "ret" from object "dest" without check of event exists
#define | WEAK_CONNECT2(ret, type0, type1, src, event, dest, handler)
| connect event "event" from object "src" to event handler "handler" with return type "ret" from object "dest" without check of event exists
#define | WEAK_CONNECT3(ret, type0, type1, type2, src, event, dest, handler)
| connect event "event" from object "src" to event handler "handler" with return type "ret" from object "dest" without check of event exists
#define | WEAK_CONNECT4(ret, type0, type1, type2, type3, src, event, dest, handler)
| connect event "event" from object "src" to event handler "handler" with return type "ret" from object "dest" without check of event exists
#define | WEAK_CONNECT WEAK_CONNECT0
| WEAK_CONNECT is synonym of WEAK_CONNECT0.
#define | DISCONNECT0(ret, src, event, dest, handler)
| piDisconnect event "event" from object "src" from event handler "handler" with return type "ret" from object "dest"
#define | DISCONNECT1(ret, type0, src, event, dest, handler)
| piDisconnect event "event" from object "src" from event handler "handler" with return type "ret" from object "dest"
#define | DISCONNECT2(ret, type0, type1, src, event, dest, handler)
| piDisconnect event "event" from object "src" from event handler "handler" with return type "ret" from object "dest"
#define | DISCONNECT3(ret, type0, type1, type2, src, event, dest, handler)
| piDisconnect event "event" from object "src" from event handler "handler" with return type "ret" from object "dest"
#define | DISCONNECT4(ret, type0, type1, type2, type3, src, event, dest, handler)
| piDisconnect event "event" from object "src" from event handler "handler" with return type "ret" from object "dest"
#define | DISCONNECT DISCONNECT0
| DISCONNECT is synonym of DISCONNECT0.
#define | HANDLER(handler)
| Returns pointer to events handler "handler".

## Detailed Description

Thread class.

This class allow you exec your code in separate thread.

# Synopsis

Multithreading allow you to write program which will be executed 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(), 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:

begin();
event started();
while (isRunning()) {
run();
ThreadFunc();
msleep(timer_delay);
}
event stopped();
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 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 timer_delay). If "func" if not null this function will be executed as run(). ThreadFunc is any static function with format void func(void * data). "Data" is custom data set from constructor or with function setData().
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.

# Locking

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

## Member Enumeration Documentation

enum PIThread::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

bool PIThread::start | ( | int | timer_delay = `-1` | ) |

Start thread.

Start execution of run() in internal loop with "timer_delay" delay in milliseconds. If "timer_delay" <= 0 there is no delay in loop. Thread also exec external function set by setSlot() if it`s not null

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

bool PIThread::start | ( | ThreadFunc | func,
|  | int | timer_delay = `-1`
| ) |  |

inline

Start thread.

Overloaded function. Set external function "func" before start

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

bool PIThread::startOnce | ( |  | ) |

Start thread without internal loop.

Start execution of run() once. Thread also exec external function set by setSlot() if it`s not null

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

bool PIThread::startOnce | ( | ThreadFunc | func | ) |

inline

Start thread without internal loop.

Overloaded function. Set external function "func" before start

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

void PIThread::stop | ( | bool | wait = `false` | ) |

inline

Stop thread.

Stop execution of thread and wait for it finish if "wait" is `true`. This function can block for infinite time if "wait" is `true` and any of thread function is busy forever

void PIThread::terminate | ( |  | ) |

Strongly stop thread.

Stop execution of thread immediately

bool PIThread::waitForStart | ( | int | timeout_msecs = `-1` | ) |

Wait for thread start.

This function block until thread finish for "timeout_msecs" or forever if "timeout_msecs" < 0

Returns
  `false` if timeout is exceeded

bool PIThread::waitForFinish | ( | int | timeout_msecs = `-1` | ) |

Wait for thread finish.

This function block until thread start for "timeout_msecs" or forever if "timeout_msecs" < 0

Returns
  `false` if timeout is exceeded