semaphore versus global

Just starting out? Need help? Post your questions and find answers here.
alokdube
Enthusiast
Enthusiast
Posts: 148
Joined: Fri Nov 02, 2007 10:55 am
Location: India
Contact:

semaphore versus global

Post by alokdube »

Hi,
Does using a global flag (set to zero and 1) and doing a repeat until flag=1 versus using a semaphore make a difference? In other words, would the semaphore waitsemaphore() be better than a: repeat until flag=1 where flag is global?
alokdube
Enthusiast
Enthusiast
Posts: 148
Joined: Fri Nov 02, 2007 10:55 am
Location: India
Contact:

Re: semaphore versus global

Post by alokdube »

or rather::

repeat
Waitwindowevent()

<some click, create threads>
...now one cannot do a semaphore wait here as it would block the code/ a spin lock would be the same.....
so it would be easier to do a

if someglobal=true do what you want with thread output
else stick to waitwindowevent loop?
until event=closewindow


so what does the semaphore give you? because either the way the internal implementation cannot be different from a spin lock (NOP till semaphore=1 kinds)
User avatar
idle
Always Here
Always Here
Posts: 5834
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: semaphore versus global

Post by idle »

If I remember correctly
waitsemephore the OS suspends the thread and switches context, it won't consume any cpu at all until you signal it.
which will force the OS to do a context change and resume the thread.

Advantages you don't need to run a loop checking for a global state or require that you to use a delay other than for enabling the thread to give up its time slice gracefully eg delay(0) if the business in the thread is going to take longer than the thread time slice.

The issue with example code below is that it has potential to block the main loop if the thread routine takes longer to run than a user clicking the button. If you didn't want that to happen you'd need to marshal the data with a mutex protected fifo, so the worker thread would just keep pulling items off the fifo unitl it's emptied the queue and then go back to sleep.

Code: Select all

 
Global gListSeme = CreateSemaphore()
Global glmut = CreateMutex()
Global grun,tidList,ct
#Gadget = 1

Procedure Test(run)
Protected i,n
grun = run
While grun
 
WaitSemaphore(gListSeme) ;thread waits here
  If grun
    Debug "signaled"
    LockMutex(glmut) ;lock mutex here as action is across thread boundary 
    For i = 0 To CountGadgetItems(#Gadget)
     Debug GetGadgetItemText(#gadget,i)
    Next i
    UnlockMutex(glmut);unlock mutex here
  EndIf
Wend   
   
EndProcedure

OpenWindow(0,0,0,200,200,"test")
ListViewGadget(#Gadget,0,0,200,180)
ButtonGadget(0,0,180,60,20,"add")

;monitor thread
tidlist = CreateThread (@test(),1)

Repeat
 
  ev = WaitWindowEvent()
  evg = EventGadget()
  evt = EventType()
  If ev = #PB_Event_Gadget 
    If evg = 0
      LockMutex(glmut);lock mutex to protect as you don't want to eat any add event 
      AddGadgetItem(#gadget,-1,"Data " + Str(ct))
      UnlockMutex(glmut) ;unlock mutex here
      SignalSemaphore(gListSeme)
      ct+1
    EndIf
  EndIf 
 
Until ev = #PB_Event_CloseWindow
Windows 11, Manjaro, Raspberry Pi OS
Image
alokdube
Enthusiast
Enthusiast
Posts: 148
Joined: Fri Nov 02, 2007 10:55 am
Location: India
Contact:

Re: semaphore versus global

Post by alokdube »

say I do not want the parent to "wait/lock".
Basically my code is a sort of brute force multithreaded board calculator (say like sudoku etc) where each thread tries something on it's own.
so it is more like
Parent...
......
....waitwindowevent()

if some event X
callthread()
.......
...parent goes on...
...if thread has reply show output else just keep going as parent...
.......
until closewindow

my front end/user interface is controlled by the main thread.
My question is more specific that even if I use trysemaphore or trylockmutex, that part of the code has to still go on as the parent does not sleep.
So in effect if I cannot halt the execution of the parent, does it make a difference if I use a global flag or is it still better to use the trysemaphore/trymutex?
Note I cannot let the parent sleep, it still has to take inputs from the user / the front end cannot "hang".
User avatar
idle
Always Here
Always Here
Posts: 5834
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: semaphore versus global

Post by idle »

marshal the data with a mutex protected fifo, so the worker thread can keep pulling items off the fifo unitll it's emptied the queue and then go back to sleep. and let the thread output the data.
so all your event loop has to do is handle user events

Code: Select all

Global gListSeme = CreateSemaphore()
Global glmut = CreateMutex()
Global NewList fifo.s() 
Global grun,tidList,ct
#Gadget = 1

Procedure Test(run)
Protected result.s
grun = run
While grun

WaitSemaphore(gListSeme) ;thread waits here
  If grun
     Debug "signaled"
    
    While ListSize(fifo()) > 0  ;possibly dangerous  
      LockMutex(glmut)    ;lock mutex 
      FirstElement(fifo())  
      result = fifo()
      DeleteElement(fifo())
      UnlockMutex(glmut)
      Delay(500) ;procees data 
      AddGadgetItem(#gadget,-1,result)
    Wend   
  EndIf
Wend   
   
EndProcedure

OpenWindow(0,0,0,200,200,"test")
ListViewGadget(#Gadget,0,0,200,180)
ButtonGadget(0,0,180,60,20,"add")

;monitor thread
tidlist = CreateThread (@test(),1)

Repeat

  ev = WaitWindowEvent()
  evg = EventGadget()
  evt = EventType()
  If ev = #PB_Event_Gadget
    If evg = 0
      LockMutex(glmut);lock mutex to protect as you don't want to eat any add event
         LastElement(fifo())
         AddElement(fifo())
         fifo() = "Data " + Str(ct) 
      UnlockMutex(glmut)
      SignalSemaphore(gListSeme)
      ct+1
    EndIf
  EndIf

Until ev = #PB_Event_CloseWindow
Windows 11, Manjaro, Raspberry Pi OS
Image
alokdube
Enthusiast
Enthusiast
Posts: 148
Joined: Fri Nov 02, 2007 10:55 am
Location: India
Contact:

Re: semaphore versus global

Post by alokdube »

buffer is a global , ring buffer kinds
so anyone can read or write to the buffer
there is a global routine for it.
Incase of ring buffers the idea is that anyone can read or write to the buffer as long as read pointer and write pointer do not overlap
so if readptr=writeptr , all data has been read
if writeptr=readptr-1 , end of buffer/cant write more data etc.
http://en.wikipedia.org/wiki/Circular_buffer
User avatar
idle
Always Here
Always Here
Posts: 5834
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: semaphore versus global

Post by idle »

a Circular buffer would still need protecting with a mutex, they are useful when you know the number of items going into it or when you want to buffer x items before pulling an item off, if the head = tail you either have to pull an item off, overwrite an entry or reallocate it.
Using a List as a Fifo is probably better when the potential queue size is unbound.
Windows 11, Manjaro, Raspberry Pi OS
Image
alokdube
Enthusiast
Enthusiast
Posts: 148
Joined: Fri Nov 02, 2007 10:55 am
Location: India
Contact:

Re: semaphore versus global

Post by alokdube »

hmm but take this case
there is 1 "reader and 1 writer" per thread1-->thread 2 pair.
the reader thread has to check if readptr=writeptr else there is data to read, and the writer thread has to check if readtptr-1=writeptr else write..
in other words, like in case of microcontrollers of assembler levels, we allocated a stack for each thread to thread communication.
Else the single buffer will have to know how to send the relevant data to the relevant thread no?
(P2P thread circular queue)
simply check if readptr!=writeptr then read data, and writer checks, if writeptr!=readptr-1 (this is a circular buffer) the write data
Simpler to do, except each thread has to check all its incoming buffers periodically.
User avatar
idle
Always Here
Always Here
Posts: 5834
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: semaphore versus global

Post by idle »

generally you'd do a read and write as one operation in a ring buffer
every time you add something to the buffer beyond a given buffer threshold you try to remove something from it.
so you shouldn't need to perform any periodic checks at all.
Windows 11, Manjaro, Raspberry Pi OS
Image
alokdube
Enthusiast
Enthusiast
Posts: 148
Joined: Fri Nov 02, 2007 10:55 am
Location: India
Contact:

Re: semaphore versus global

Post by alokdube »

I am not sure what you mean here but micros and board levels have no schedulers. It is always "each to his own".. remember back to back unix sockets? there is no "multicast socket" the writer has to write to all unicasts.
Post Reply