Olá pessoal, quero solicitar uma ajuda de vocês para tentar resolver um problema que estou tendo ao utilizar Thread no xHarbour. Com base nas pesquisas e no Help do xHabour chequei a esse código
Porém ao executa-lo o sistema simplesmente aborta sem dar nenhum tipo de mensagem de erro. Fiz alguns "debugs" e percebi que da erro na função StartThread()
Olá UAC,
Não querendo lhe desanimar, mas o MT do xHarbour não funciona corretamente, se queres usar MT sem dor de cabeça migre para Harbour que funciona redondo. Boa sorte.
As threads criadas na apliacao não podem ter comando de tela se for uma aplicacao Windows, portanto o erro está na função MSGINFO. Somente pode ter comandos que criam DIALOG ou qualquer outra coisa na ROTINA PAI (os filhos são todas as funcoes executadas a partir do StartThread).
Voce pode fazer um teste compilando somente CONSOLE, neste caso pode sim ter comando de tela.
Como o SYGECON disse, thread não funciona bem com xHarbour. Parece que no Harbour a coisa funciona bem por usar o conceito de threadsafe, ou seja, as threads filhas criam uma partição de memória independente da pai. No xHarbour não é assim.
Conselho meu: Caia fora de thread em xHarbour, eu mesmo já passei grandes apuros com isso em 2007 quando implementamos rotinas multithread em nossas aplicações que davam GPFs inexplicaveis e erros absurdos. Após meses e meses de dor de cabeça depurando codigo sem encontrar nada abolimos as threads, mudando todo conceito dos programas que usavam isso e ai os problemas SUMIRAM !!!
Em Harbour pode ser que a coisa funcione legal, mas xHarbour eu garanto que voce vai se dar muito mal usando multi thread.
Uma boa leitura para entender o quanto o xHarbour ficou para trás...
Eu sei, está em inglês, mas para quem não quer perder tempo basta ler o último parágrafo.
Eu sei que algumas pessoas criaram programas MT usando o xHarbour, mas para mim
o atual modo MT do xHarbour não está pronto para produção. Pelo menos, está muito
longe da funcionalidade do Harbour atual e da qualidade.
### MULTI THREAD SUPPORT ###
==================================
Both compilers support multi thread programming and in both
compilers to use threads it's necessary to use MT version of VM.
In Harbour it's only single HVM library because in both versions
(ST and MT) Harbour VM gives exactly the same public API so it's
not necessary to create separate versions of any other libraries
or create different .prg code for MT and ST modes.
The separate ST version of VM can be linked with applications
which do not create any threads to improve the performance because
it's a little bit faster then MT VM. The speed difference can be
compared using speedtst.prg (results below). For other platforms/C
compilers it may be a little bit bigger or smaller anyhow it's
not very huge and Harbour in MT mode is still much faster then
xHarbour in ST mode.
For .prg programmer the only difference between applications linked
with single thread VM and multi thread VM is in hb_threadStart()
results. This function linked with ST VM always fails and new thread
is never created.
Harbour gives set of functions with hb_thread*() and hb_mutex*()
prefix to manage threads and synchronize them. It also supports
THREAD STATIC variables what allows to easy adopt any existing code
to MT mode. Whole Clipper compatible .prg API using internally static
variables like GET system was adopted for MT mode and work with thread
local statics.
Most of core code had been rewritten to be reentrant safe so it does
not have to be protected by any mutexes what greatly helps in
scalability. Below is a short description which shows which resources
are thread local which ones are shared and how they are initialized:
Thread attributes inherited from parent thread:
- code page
- language
- SETs
- default RDD
- active GT driver/console window
- I18N translation set
Thread attributes initialized to default value:
- public variable GetList := {}
(of course if public variables are not shared with parent
thread).
- error block (initialized by calling ERRORSYS())
- math error handler and math error block
- default macro compiler features setting (controlled by
hb_setMacro())
- RDDI_* settings in core RDDs (some 3-rd party RDDs may use
global settings)
- thread static variables
Resources which can be shared or copied form parent to child thread
on user request when thread is created:
- public variables
- private variables
Global resources synced automatically:
- functions and procedures
- class definitions
- RDDs
- GT drivers
- lang modules
- codepage modules
Global resources:
- .prg static variables (Harbour core code does not use them)
Thread local resources:
- memvar (public and private) variables (except the ones which
are shared with parent threads)
- work areas
- thread static variables
In practice the only one not synced automatically element in Harbour
is write access to the same item with complex variable. This part
have to be synced by user and automatic synchronization here will
strongly reduce scalability.
Harbour also support xBase++ compatible MT API with SYNC and CLASS SYNC
methods, SIGNAL and THREAD classes, workarea zones and thread functions.
It allows to easy port xbase++ code to Harbour. The main difference
between Harbour and xbase++ is write protection to complex items.
Harbour gives only read protection so threads can access the same
complex variable simultaneously without any restrictions as long
as it's not modified (assigned) by some other thread. Assign operations
to variable which can be accessed simultaneously by other threads
need explicit synchronization by user code. In xBase++ it should
be synced automatically so users have to use own synchronization
only to keep synced his application logic.
For sure xBase++ is more user friendly here. Anyhow such solution
strongly reduce scalability so the cost of such automatic protection
is very high. Additionally in most of cases simultaneous access and
assign operations on the same complex variable need additional
user synchronization to eliminate race condition so it does not
help much in real programming. Anyhow it's interesting in some
cases so it's possible that we add such functionality to Harbour
in alternative HVM library to not reduce current performance.
In xHarbour for MT mode it's necessary to use different set of RTL libraries
not only MT version of VM lib. MT mode change the behavior of core features
and many parts of xHarbour core code have been never adopted to MT mode so
it's hard to clearly define which resources are thread local and which ones
are global and what should be synchronized by user. Many things are not
synced at all and race conditions can cause internal HVM structure
corruptions, i.e. class creation code where many threads can try to
register the same class simultaneously so it needs yet a lot of work to
reach real production functionality. It also needs serious cleanup because
there are race conditions even in basic MT API. Missing from the beginning
clear definition of MT mode caused that in last years not all xHarbour
modifications were MT safe and some of them even broke existing functionality.
xHarbour MT API is present only in MT version of HVM and supports only some
subset of Harbour functionality.
The only one xHarbour MT feature not existing in current Harbour code is
support for:
CRITICAL [STATIC] FUNCTION | PROCEDURE( [<xParams,...> )
but in current xHarbour CVS such functionality is broken. The problem can
be seen at compile time so looks that none of core developers were using
it in last years. This feature in xHarbour was implemented only in .c
code generated by xHarbour compiler (-gc[0-3] output) so it was never
working with .hrb (-gh) files or some interpreters like xBaseScript.
xHarbour has support for SYNC methods which were designed to replicate
xBase++ functionality but their real behavior is not xBase++ and Harbour
compatible at all. It seems to be close to SYNC CLASS method in xBase++
and Harbour though it's not exactly the same. There is no support for
real SYNC methods like in xBase++ and xBase++ MT programming functions
and classes.
In summary MT mode in xHarbour looks like a work in progress, started few
years ago and never finished. Instead some other core code modifications
in last years systematically introduced new non MT safe code and in few
cases even broke existing MT extensions.
I cannot say if xHarbour developers plan to make sth with it.
Now I cannot even describe it well because looking at the xHarbour source
I do not know what is intentional decision, what is a bug in implementation
and what is unfinished code, i.e. such code:
JoinThread( StartThread( @func() ) )
in xHarbour has race condition and can generate RT error if new thread
finished before join operation begin. For me it's bad design decision
or fatal side effect of wrong implementation but I do not plan to guess.
This is very trivial example and I see in core code much more serious
and more complicated problems I had to resolve in Harbour which are not
touched at all in xHarbour.
I know that some people created MT programs using xHarbour but for me
current xHarbour MT mode is not production ready. At least it is very
far from current Harbour functionality and quality.