Post by Enrico Maria GiordanoDear friends, I'd like to know where to find informations about the
current state of the Harbour support for multithreading and if it's
stable enough to be used in the applications.
Many thanks in advance.
Look at:
doc/xhb-diff.txt: "MULTI THREAD SUPPORT"
In Harbour MT mode is fully functional and AFAIK is production ready
without any known bugs except 4 document problems which has not been
addressed and maybe never will be because they are not strictly
necessary to create final applications:
1. Tracelog is not MT safe. It's not a big problem for normal
applications because this code is disabled in standard builds and
enabled only on explicit user request during Harbour compilation
to debug some Harbour internals so it's rather for developers only.
2. PROFILLER cannot collect information for each thread separately.
It's optional code disabled by default. Before we will touch it
please think how it should work for MT programs.
3. DEBUGGER: only main thread debugger can see the names of file wide
STATICs and have information about line numbers with good break
points. We should add code to share this information between threads.
4. hb_threadQuitRequest() can be ignored by thread in some cases
due to race condition. It may happen if thread will overwrite
request send by caller simultaneously, f.e. by its own BREAK.
I can resolve it but we can also leave it as is and document
such behavior as expected or even remove this function. Killing
other threads in such way is dangerous and can be used only
for some simple situation. It's much safer when user uses his
own mechanism to terminate treads in some safe for his code places.
Harbour PRG level API:
hb_threadStart( [<nThreadAttrs> ,] <@sStart()> | <bStart> | <cStart> [, <params,...> ] ) -> <pThID>
hb_threadSelf() -> <pThID> | NIL
hb_threadId( [ <pThID> ] ) -> <nThNo>
hb_threadJoin( <pThID> [, @<xRetCode> ] ) -> <lOK>
hb_threadDetach( <pThID> ) -> <lOK>
* hb_threadQuitRequest( <pThID> ) -> <lOK>
hb_threadTerminateAll() -> NIL
hb_threadWaitForAll() -> NIL
hb_threadWait( <pThID> | <apThID>, [ <nTimeOut> ] [, <lAll> ] ) => <nThInd> | <nThCount> | 0
hb_threadOnce( @<onceControl> [, <bAction> ] ) -> <lFirstCall>
hb_mutexCreate() -> <pMtx>
hb_mutexLock( <pMtx> [, <nTimeOut> ] ) -> <lLocked>
hb_mutexUnlock( <pMtx> ) -> <lOK>
hb_mutexNotify( <pMtx> [, <xVal>] ) -> NIL
hb_mutexNotifyAll( <pMtx> [, <xVal>] ) -> NIL
hb_mutexSubscribe( <pMtx>, [ <nTimeOut> ] [, @<xSubscribed> ] ) -> <lSubscribed>
hb_mutexSubscribeNow( <pMtx>, [ <nTimeOut> ] [, @<xSubscribed> ] ) -> <lSubscribed>
* - this function call can be ignored by the destination thread in some
cases. HVM does not guaranties that the QUIT signal will be always
delivered.
xBase++ compatible functions and classes:
ThreadID() -> <nID>
ThreadObject() -> <oThread>
ThreadWait( <aThreads>, <nTimeOut> ) -> <xResult>
ThreadWaitAll( <aThreads>, <nTimeOut> ) -> <lAllJoind>
Thread() -> <oThread> // create thread object
Signal() -> <oSignal> // create signal object
Harbour supports also SYNC methods and SYNC class method implementing
original xBase++ behavior.
It also supports xBase++ concept of moving workareas between threads
using functions like dbRelease() and dbRequest().
In tests/mt you will find few simple test programs for MT mode.
Some of Harbour tools like hbmk2 or uhttpd[2] (examples/httpsrv,
/examples/uhttpd2) use extensively MT mode.
best regards,
Przemek