Hi Francesco,

> The problem is that I need that SET_BACKGORUNDTASKS has to be shared 
> between threads, this is because threads have to be stopped or activated 
> based on above set.

In MT mode threads are executes independently. We do not have
task switching at HVM level but we use OS threads. It means
that for programmer each thread is executed simultaneously and
even on single CPU machine programmer does not know when the
CPU is switched between threads.
Some OS-es allow to suspend some thread(s) but people are often
confused by this functionality thinking that it allows to exected
any single thread code at any moment. It's not true and does not
help in synchronization because programmer does not know the place
where the thread was suspend so he does not know if it's safe to
execute some code. In fact code which uses such functionality cannot
use mutexes after calling thread suspend because suspending other
thread with active lock will cause deadlock.

Where do you want to keep list of background tasks and if you want
or not share them between threads it's your decision. But it's not
directly related to suspending other threads during execution of
bkg tasks. Just simply user have to create tasks which will not
break jobs executed by other threads. Otherwise you reduce foreground
threads to simple task switching.

> In my repository I have background tasks that in ST mode works well and 
> I can stop / restart using above set.

If you port it to MT mode as is keeping the task list in thread dependent
area then each thread will have such list of background tasks.

> On the contrary I have implemented background tasks in MT mode using 
> your sample (plus some refinements) but once the thread is started I 
> cannot control flow using above set.

because it does not respect them. In the code I sent the task are
executed simultaneously to other threads (without stopping them) in given
time periods. If you need some other switches f.e. manipulating of time
periods then you need to extend this code. It was only simple example.

> And as you state above, there are some sets that is useful to have shared.
> So how can I share it ?

You have to change set.c and implement their low level storage and actions
in shared area but in this case I think it's still not the thing you are
asking for. I think you will want to stop all threads in some arbitrary
point and execute bkg task by one of existing threads and then wake up
all. It's possible and GC uses it though with some additional conditions
but it's not good idea to create other code which make sth like that.

> And another problem is about screen updates.
> Once the thread is started too many screen updates are done in wrong 
> places also if all updates are guarded with Row()/Col() save and restore.

because it's real MT mode. Many thread using the same GT console window can
simultaneously update the screen and change cursor position. Harbour only
makes technical internal data protection against corruption but it does
not know anything about logical screen updates you need to synchronize
screen output in your application.
F.e. in some of tests/mt/mttest*.prg programs threads are displaying
data in simultaneously and the output is merged. It's intentional so you
can see which thread is active. But in some other programs you may want
to separate screen output.
F.e. in bkg tasks, if you do not want to change cursor position during
screen update then you should use screen functions which does not change it.
Save/restore row()/col() do not help because these are yet another functions
which change cursor position when other threads still may use it.

F.e. in the code below thread display clock. It uses HB_DISPOUTAT() to not
change cursor position. Check what will happen if you will use DISPOUTAT().

best regards,
Przemek



proc main()
   local getList := {}
   local cVar := space( 20 )

   hb_threadStart( @thFunc() )

   CLEAR SCREEN
   @ 10, 10 SAY "Insert cVar:" GET cVar
   READ
   SetPos( 12, 0 )
   ? "Result -> [" + cVar + "]"
   WAIT

return

func thFunc()
   local cTime
   while .T.
      cTime := dtoc( date() ) + " " + time()
      hb_dispOutAt( 0, maxcol() - len( cTime ) + 1, cTime, "GR+/N" )
      hb_idleSleep( 1 )
   enddo
return nil
_______________________________________________
Harbour mailing list
Harbour@harbour-project.org
http://lists.harbour-project.org/mailman/listinfo/harbour

Reply via email to