Page 1 of 1

Multiple threads sleep for x seconds ?

Posted: Thu Jan 25, 2018 6:48 pm
by xakep
For example I want to have two threads, one that calls an procedure at each 2 seconds and another one that calls an procedure at each 6 seconds.
This code need to run forever, untill the program is closed.

What i got for now:

Code: Select all

EnableExplicit

Procedure Thread1()
  Define hEvent.l
  
  hEvent = CreateEvent_(#Null, #True, #False, #Null$)
  
  If hEvent
    WaitForSingleObject_(hEvent, 2000)
    CloseHandle_(hEvent) 
    
    Debug "Task each 2 seconds"
    
    Thread1()
  EndIf
  
EndProcedure

Procedure Thread2()
  Define hEvent.l
  
  hEvent = CreateEvent_(#Null, #True, #False, #Null$)
  
  If hEvent
    WaitForSingleObject_(hEvent, 6000)
    CloseHandle_(hEvent)
    
    Debug "Task each 6 seconds"
    
    Thread2()
  EndIf

EndProcedure

Procedure Main()
  Define hEvent.l
  
  Dim Threads.l(1)
  Threads(0) = CreateThread_(#Null, 0, @Thread1(), #Null, 0, #Null)
  Threads(1) = CreateThread_(#Null, 0, @Thread2(), #Null, 0, #Null)

  WaitForMultipleObjects_(2, @Threads(), #True, #INFINITE)
  
  CloseHandle_(Threads(0))
  CloseHandle_(Threads(1))
  
EndProcedure

Main()
This code works fine, but i think is not right.
Also, i want to do all this without using Sleep, as sleep will pause whole program and not only the thread.

Thanks for you time

Re: Multiple threads sleep for x seconds ?

Posted: Thu Jan 25, 2018 7:04 pm
by skywalk
Your Main() has no event loop?
It would be easier to accomplish your goal with a Window Timer that trigger your threads.
Assuming your threads conclude before their next call to action.
But, you can query that also in the code flow.

Re: Multiple threads sleep for x seconds ?

Posted: Thu Jan 25, 2018 7:25 pm
by nco2k
xakep wrote:sleep will pause whole program and not only the thread.
thats not true. sleep will pause the current thread.

https://msdn.microsoft.com/de-de/librar ... s.85).aspx

c ya,
nco2k

Re: Multiple threads sleep for x seconds ?

Posted: Thu Jan 25, 2018 8:03 pm
by xakep
@nco2k
Yeap, seems like that works too:

Code: Select all

EnableExplicit

Procedure Thread1()
  Sleep_(2000)
  
  Debug "Task each 2 seconds"
  
  Thread1()
EndProcedure

Procedure Thread2()
  Sleep_(6000)
  
  Debug "Task each 6 seconds"
  
  Thread2()
EndProcedure

Procedure Main()
  Define hEvent.l
 
  Dim Threads.l(1)
  Threads(0) = CreateThread_(#Null, 0, @Thread1(), #Null, 0, #Null)
  Threads(1) = CreateThread_(#Null, 0, @Thread2(), #Null, 0, #Null)

  WaitForMultipleObjects_(2, @Threads(), #True, #INFINITE)
 
  CloseHandle_(Threads(0))
  CloseHandle_(Threads(1))
 
EndProcedure

Main()
But my point is if there's some safer way to do all this.
Recalling same procedure over and over might corrupt the stack, i suppose.

Re: Multiple threads sleep for x seconds ?

Posted: Thu Jan 25, 2018 8:24 pm
by nco2k
thats why you should use a loop:

Code: Select all

Global QuitThread1
Procedure Thread1()
  Repeat
    Sleep_(2000)
    Debug "Task each 2 seconds"
  Until QuitThread1
EndProcedure
but Sleep_() isnt very accurate by default. dont know if thats important for you. also when you want to exit the thread, you would have to wait first, until those x seconds passed. you could use the delay in smaller chunks. or create a waitable timer. or a timer with no window, but a message loop. or an invisibile window. or a message only window. there are a gazillion options.

do some research and decide for yourself. after all, you are the one who knows whats best for your application.

edit: or of course you could stick with the method you are already using:

Code: Select all

EnableExplicit

Global Dim Threads(1), Dim Events(1)

Procedure Thread1()
  While WaitForSingleObject_(Events(0), 2000) = #WAIT_TIMEOUT
    Debug "Task each 2 seconds"
  Wend
EndProcedure

Procedure Thread2()
  While WaitForSingleObject_(Events(1), 6000) = #WAIT_TIMEOUT
    Debug "Task each 6 seconds"
  Wend
EndProcedure

Procedure Main()
  
  Events(0) = CreateEvent_(#Null, #True, #False, #Null)
  If Events(0)
    
    Threads(0) = CreateThread_(#Null, 0, @Thread1(), #Null, #CREATE_SUSPENDED, #Null)
    If Threads(0)
      
      Events(1) = CreateEvent_(#Null, #True, #False, #Null)
      If Events(1)
        
        Threads(1) = CreateThread_(#Null, 0, @Thread2(), #Null, #CREATE_SUSPENDED, #Null)
        If Threads(1)
          
          Debug "Starting Threads..."
          
          ResumeThread_(Threads(0))
          ResumeThread_(Threads(1))
          
          Sleep_(7000)
          
          Debug "Finishing Threads..."
          
          SetEvent_(Events(0))
          SetEvent_(Events(1))
          
          WaitForMultipleObjects_(ArraySize(Threads()) + 1, @Threads(), #True, #INFINITE)
          
          CloseHandle_(Threads(1))
        EndIf
        
        CloseHandle_(Events(1))
      EndIf
      
      CloseHandle_(Threads(0))
    EndIf
    
    CloseHandle_(Events(0))
  EndIf
  
EndProcedure

Main()
and btw handles are integers (.i) not longs (.l).

c ya,
nco2k

Re: Multiple threads sleep for x seconds ?

Posted: Fri Jan 26, 2018 6:27 pm
by xakep
@nco2k Great. Thanks alot )