Multiple threads sleep for x seconds ?

Just starting out? Need help? Post your questions and find answers here.
xakep
User
User
Posts: 40
Joined: Fri Mar 25, 2016 2:02 pm
Location: Europe

Multiple threads sleep for x seconds ?

Post 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
User avatar
skywalk
Addict
Addict
Posts: 4210
Joined: Wed Dec 23, 2009 10:14 pm
Location: Boston, MA

Re: Multiple threads sleep for x seconds ?

Post 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.
The nice thing about standards is there are so many to choose from. ~ Andrew Tanenbaum
User avatar
nco2k
Addict
Addict
Posts: 1344
Joined: Mon Sep 15, 2003 5:55 am

Re: Multiple threads sleep for x seconds ?

Post 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
If OSVersion() = #PB_OS_Windows_ME : End : EndIf
xakep
User
User
Posts: 40
Joined: Fri Mar 25, 2016 2:02 pm
Location: Europe

Re: Multiple threads sleep for x seconds ?

Post 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.
User avatar
nco2k
Addict
Addict
Posts: 1344
Joined: Mon Sep 15, 2003 5:55 am

Re: Multiple threads sleep for x seconds ?

Post 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
If OSVersion() = #PB_OS_Windows_ME : End : EndIf
xakep
User
User
Posts: 40
Joined: Fri Mar 25, 2016 2:02 pm
Location: Europe

Re: Multiple threads sleep for x seconds ?

Post by xakep »

@nco2k Great. Thanks alot )
Post Reply