Built-in Coroutines

Got an idea for enhancing PureBasic? New command(s) you'd like to see?
User avatar
fsw
Addict
Addict
Posts: 1603
Joined: Tue Apr 29, 2003 9:18 pm
Location: North by Northwest

Built-in Coroutines

Post by fsw »

Here I show how yielding threads (like coroutines) can be created.

Would be nice to get this done by the compiler.

Here how it could look like:

Code: Select all

Global Task.s

CoProcedure Producer(Total) 

  For i = 1 To Total
    ; automatic task mutex lock to be thread-safe
    Task = "bake bread"
    PrintN(Task)

    YieldsTo Consumer()
  Next i  
    
EndCoProcedure

CoProcedure Consumer(Total) 

  For i = 1 To Total  
    YieldsTo Producer()
    
    ; automatic task mutex lock to be thread-safe
    Task = "eat bread"
    PrintN(Task)
   
  Next i 

EndCoProcedure

; main
OpenConsole("Coroutines-like sequential process")

; it could also be named CreateCoProcedure()
If CreateCoroutine(@Producer(), 30) 
  CreateCoroutine(@Consumer(), 30)
EndIf

Input()

CloseConsole()
Don't know what it takes to implement this, but certainly it would be UEBER 8)
(or something similar...)

I am to provide the public with beneficial shocks.
Alfred Hitshock
User avatar
Danilo
Addict
Addict
Posts: 3036
Joined: Sat Apr 26, 2003 8:26 am
Location: Planet Earth

Re: Built-in Coroutines

Post by Danilo »

The example does not make much sense IMO, as it could be made with 1 thread (PrintN("bake bread") : PrintN("eat bread") : repeat).

Do you have some better examples or could you explain a bit more please? What do you want to do exactly, that you can't do already with threads?

Code: Select all

Macro CoProcedure    : Procedure    : EndMacro
Macro EndCoProcedure : EndProcedure : EndMacro

Global yieldTarget.s

Procedure CreateCoroutine(*procedure, argument)
    ProcedureReturn CreateThread( *procedure, argument )
EndProcedure

Macro DQ
    "
EndMacro

Macro YieldsTo( _CoRoutine_ )
    yieldTarget = DQ#_CoRoutine_#DQ
    Repeat
        CompilerIf #PB_Compiler_OS = #PB_OS_Windows
            SwitchToThread_()
        CompilerElse
            Delay(1)
        CompilerEndIf
    Until yieldTarget = #PB_Compiler_Procedure + "()"
EndMacro


;-----------------------------------------------------------

Global Task.s

CoProcedure Producer(Total) 

  For i = 1 To Total
    ; automatic task mutex lock to be thread-safe
    Task = "bake bread"
    PrintN(Task)

    YieldsTo( Consumer() )
  Next i  
    
EndCoProcedure

CoProcedure Consumer(Total) 

  For i = 1 To Total  
    YieldsTo( Producer() )
    
    ; automatic task mutex lock to be thread-safe
    Task = "eat bread"
    PrintN(Task)
   
  Next i 

EndCoProcedure

; main
OpenConsole("Coroutines-like sequential process")

; it could also be named CreateCoProcedure()
If CreateCoroutine(@Producer(), 30) 
  CreateCoroutine(@Consumer(), 30)
EndIf

Input()

CloseConsole()
User avatar
luis
Addict
Addict
Posts: 3895
Joined: Wed Aug 31, 2005 11:09 pm
Location: Italy

Re: Built-in Coroutines

Post by luis »

I never really felt the need for co-routines, anyway here is an example that explains quite well a typical usage scenario (and how they can be "faked" using a language near enough to PB, just to have a general idea about how you can approach the problem)

http://www.chiark.greenend.org.uk/~sgta ... tines.html
"Have you tried turning it off and on again ?"
A little PureBasic review
User avatar
fsw
Addict
Addict
Posts: 1603
Joined: Tue Apr 29, 2003 9:18 pm
Location: North by Northwest

Re: Built-in Coroutines

Post by fsw »

Thank you Luis for jumping in.

The more I work with "Go" (golang) I find that my own thinking pattern - while coding - changes from building code that is crafted to do one thing right (working from top to bottom until the task is done) into creating code that is far more flexible and reusable for different applications. For this producers/generators and listeners/receivers need to be build. Once the work is done the application is as fast as it can be without bogging down the whole system in times where a lot of "data traffic" is happening.

Sure the same can be accomplished with threads or even without threads, but depending on the application at hand the system might experience some trouble, like the GUI is unresponsive because a thread is sucking most of the CPU time - inserting delays into the thread only mask an issue (in another forum-thread it was said inserting delays is the "better" solution...). When an application is developed and used for 5 or 10 years all these little delays may even slow down the application more then need be. Or if you create a thread-less application you can only use the code for this specific application; every time you try to reuse the code you end up rewriting most of it anyway.

As Luis' link (using C) showed coroutines can be created without being build into the language.
In the end build-in coroutines are not a "must have" but a "nice to have" thing.

Also every one is entitled to a different opinion :wink:

Sorry that the bake bread/eat bread example was too simple for you...
Last edited by fsw on Fri Mar 01, 2013 8:53 pm, edited 1 time in total.

I am to provide the public with beneficial shocks.
Alfred Hitshock
freak
PureBasic Team
PureBasic Team
Posts: 5940
Joined: Fri Apr 25, 2003 5:21 pm
Location: Germany

Re: Built-in Coroutines

Post by freak »

fsw wrote:(in another forum-thread it was said inserting delays is the "better" solution...).
The Delay() was there to _simulate_ actual work. It was just an example.

If you want to utilize the processing power of today's computers you have to use threads. Coroutines don't make anything faster. They are just a different way of writing a single-threaded program.
quidquid Latine dictum sit altum videtur
User avatar
fsw
Addict
Addict
Posts: 1603
Joined: Tue Apr 29, 2003 9:18 pm
Location: North by Northwest

Re: Built-in Coroutines

Post by fsw »

freak wrote:If you want to utilize the processing power of today's computers you have to use threads. Coroutines don't make anything faster. They are just a different way of writing a single-threaded program.
Suppose it depends on the implementation.
In Go it's not single-threaded, and in my PureBasic example it's not single-threaded either.

Anyway, as I said: every one is entitled to a different opinion :wink:

I am to provide the public with beneficial shocks.
Alfred Hitshock
Post Reply