Page 1 of 1

Calling SignalSemaphore()'s during PauseThread()

Posted: Fri Sep 02, 2016 12:29 pm
by Joris
Hi,

I'm still learning on this and so some questions...

I got a thread in my prog which is called from different possible user-actions with SignalSemaphore()'s in the program.
At certain moment all those SignalSemaphore()-call's must be disabled (another thread will then become in use), and later on again become active.

To stop any SignalSemaphore()-call which increases the semaphore count, should I use :
* PauseThread() (which is the easiest way as it is one command) ?
* dissable all SignalSemaphore()-call's for that Thread ?
(difficult as there are many)
* KillThread() ?
* TrySemaphore() but where to place ?

Thanks.

Re: Calling SignalSemaphore()'s during PauseThread()

Posted: Fri Sep 02, 2016 2:03 pm
by mk-soft
The problem with "PauseThread ()" is the stand remains the thread somewhere in the code.
In "KillThread() it may be that resourcen not be relased.

I think the best way is the thread about commandos to be controlled.

I have two example for threads...

http://www.purebasic.fr/english/viewtop ... 12&t=64084
http://www.purebasic.fr/english/viewtop ... 12&t=65774

:wink:

Re: Calling SignalSemaphore()'s during PauseThread()

Posted: Fri Sep 02, 2016 4:40 pm
by PureFox
I'm not entirely sure from the question whether the calls to SignalSemaphore() are in the thread procedure itself or in your other code.

If it's the former, then calling PauseThread() is the best solution since it will clearly prevent any calls to SignalSemaphore() during the period of suspension. A call to ResumeThread() will then allow the semaphore(s) to be signalled again.

If it's the latter (which I think is what @mk-soft assumed), then PauseThread() or KillThread() will have no effect on the semaphores as they are not 'owned' by any particular thread. You will therefore have to disable (or bypass) the calls to SignalSemaphore() individually.

AFAIK, there is no way to disable a semaphore in PB other than by freeing it (and its associated OS resources) altogether. You'd then need to recreate the semaphore when it was needed again which may not be a particularly attractive option.

Whilst you can reduce a semaphore's internal count to zero by calling TrySemaphore() in a Repeat/Until loop, this of course won't prevent calls to SignalSemaphore() from incrementing the count again.

So I think you'd need to write code to bypass the individual SignalSemaphore() calls if a certain condition were true.

Re: Calling SignalSemaphore()'s during PauseThread()

Posted: Fri Sep 02, 2016 6:56 pm
by Joris
Hi,

Thanks guy's, yet I think you need a bit more info, so I tried to make a compact sample of my code setup.
Maybe the little code part below will explain better, as it show's how I've set things up.

The two threads which will come in use, according a switch is disabled or enabled (not together).
The SignalSemaphore(sema_update_data) is called from different places, activated by some gadgets (events).

Would this idea be possible :
Can I just set the variable sema_update_data to zero instead of de-activating all the SignalSemaphore(sema_update_data) ?
So stop any further SignalSemaphore(sema_update_data)-call's which increases the semaphore count. Later on reset the sema_update_data variable.
(Instead of using the TrySemaphore() in a loop untill the SignalSemaphore(sema_update_data) counters restart from 0 ?)

Code: Select all

Global thread_update_data.i = CreateThread(@Update_Play_Data(), @thread_Info)
If thread_update_data
  Global sema_update_data.i = CreateSemaphore()
  Global mut_update_data.i = CreateMutex()
  oldPriority=ThreadPriority(thread_update_data, 30)
EndIf
Global thread_show_data.i = CreateThread(@Update_Song_data(), @thread_Info)
If thread_show_data
  Global sema_show_data.i = CreateSemaphore()
  Global mut_show_data.i = CreateMutex()
  PauseThread(thread_show_data)     ;paused untill a switch is enabled (which then PauseThread(thread_update_data)
EndIf
...

Procedure Update_Data(adres.i)
  Protected *thread.THREAD_DATA
  Repeat 
    WaitSemaphore(sema_update_data) 
    LockMutex(mut_update_data)     
    ...
    ...
    ...
    UnlockMutex(mut_update_data)     
  Until gclose    
EndProcedure 
Procedure Show_Data(adres.i)
  Protected *thread.THREAD_DATA
  Repeat 
    WaitSemaphore(sema_show_data) 
    LockMutex(mut_show_data)     
    ...
    ...
    ...
    UnlockMutex(mut_show_data)     
  Until gclose    
EndProcedure 

SignalSemaphore(sema_update_data) 
...
SignalSemaphore(sema_show_data) 
Thanks

Re: Calling SignalSemaphore()'s during PauseThread()

Posted: Fri Sep 02, 2016 7:45 pm
by PureFox
I think, if you do that, then you'll get an error that there's no semaphore with a handle of 0 when you call SignalSemaphore().

However, what should work is to create a third semaphore where you're not bothered whether the count is incremented or not. You can then set your global variable to this semaphore and, later on, reset it to the one you actually want to use. The code would be something like this:

Code: Select all

Global thread_update_data.i = CreateThread(@Update_Play_Data(), @thread_Info)
If thread_update_data
  Global sema_update_data.i = CreateSemaphore()
  Global mut_update_data.i = CreateMutex()
  oldPriority=ThreadPriority(thread_update_data, 30)
EndIf
Global thread_show_data.i = CreateThread(@Update_Song_data(), @thread_Info)
If thread_show_data
  Global sema_show_data.i = CreateSemaphore()
  Global mut_show_data.i = CreateMutex()
  PauseThread(thread_show_data)     ;paused untill a switch is enabled (which then PauseThread(thread_update_data)
EndIf

[b]Global sema_temp.i = CreateSemaphore()[/b]
...

Procedure Update_Data(adres.i)
  Protected *thread.THREAD_DATA
  Repeat 
    WaitSemaphore(sema_update_data) 
    LockMutex(mut_update_data)     
    ...
    ...
    ...
    UnlockMutex(mut_update_data)     
  Until gclose    
EndProcedure 
Procedure Show_Data(adres.i)
  Protected *thread.THREAD_DATA
  Repeat 
    WaitSemaphore(sema_show_data) 
    LockMutex(mut_show_data)     
    ...
    ...
    ...
    UnlockMutex(mut_show_data)     
  Until gclose    
EndProcedure 

[b]sema_update_data = sema_temp[/b]
SignalSemaphore(sema_update_data) 
...

[b]sema_show_data = sema_temp[/b]
SignalSemaphore(sema_show_data) 


Re: Calling SignalSemaphore()'s during PauseThread()

Posted: Sat Sep 03, 2016 9:42 am
by Joris
Ok thanks guys.

@PureFox I will try the setup with a third thread.
I can make that with a simple messagebox (warning) then to show that the 'original function' is not in use for that moment.