Calling SignalSemaphore()'s during PauseThread()

Just starting out? Need help? Post your questions and find answers here.
Joris
Addict
Addict
Posts: 890
Joined: Fri Oct 16, 2009 10:12 am
Location: BE

Calling SignalSemaphore()'s during PauseThread()

Post 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.
Yeah I know, but keep in mind ... Leonardo da Vinci was also an autodidact.
User avatar
mk-soft
Always Here
Always Here
Posts: 6239
Joined: Fri May 12, 2006 6:51 pm
Location: Germany

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

Post 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:
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
PureFox
New User
New User
Posts: 5
Joined: Mon Aug 22, 2016 9:17 pm

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

Post 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.
Joris
Addict
Addict
Posts: 890
Joined: Fri Oct 16, 2009 10:12 am
Location: BE

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

Post 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
Yeah I know, but keep in mind ... Leonardo da Vinci was also an autodidact.
PureFox
New User
New User
Posts: 5
Joined: Mon Aug 22, 2016 9:17 pm

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

Post 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) 

Joris
Addict
Addict
Posts: 890
Joined: Fri Oct 16, 2009 10:12 am
Location: BE

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

Post 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.
Yeah I know, but keep in mind ... Leonardo da Vinci was also an autodidact.
Post Reply