Thread: coroutines in C
nop_90

http://goron.de/~froese/coro/coro.html
I have not tried this one, just for reference

scheme has continuations, which you can use to freeze/restart a state of a thread.
(a little more complex then that but idea)

Anyway if someone was smart, use coro, then use multi curl with it.
then u could avoid complexity Applause

dink

Gotta reply to this thread, Nop.  That way I can find it again later.  Thnx

nop_90

I was tired when i wrote it.
Anyway if you are doing

PHP

 /

Perl

 /

Python

  etc you would have to make a wrapper.
(if those languages do something crazy with the stack you are in big trouble and i suspect that it will not work or something nasty will happen Applause)
Also if you use this and native threads combined that nasty will happen.

I think (don't quote me on this) that it uses the same technique that chicken scheme uses.
chicken scheme is a scheme to C compiler, but its calls never return (so args stay allocated on the stack)
(scheme calls never return, hence that is how u can do tail recursion and shit like that).
chicken scheme is extremely fast, and in some cases when it comes to recursion can outperform hand written C code.
(how the fuk it works to be honest i am not 100% sure, read the fuking paper on how it works and if ur head does not blow up)

Python

  and ruby have continuations, but in ruby very slow, since they are saving all local vars on before they go into co-routine/continuation.

Anyway make wrapper for

PHP

 /

Perl

 /

Python

  (not that hard in that case, u could probably just run the fisher thru swig).
then away u go.
I suspect should be no problem since someone make binding for SBCL (a lisp) and he have no problem.
If you are doing

python

  (i know must be same shit for

PHP

  etc) make sure you lock and unlock the global interpreter lock or u get nasty, (probably could get away with not doing this).

Using scheme and this method you can have 20/40 sockets open on a single thread, and ur shitbox vps can outperform a dedicated server.

dink

Ya.  I still have that linky you gave me for chicken.

I downloaded the PDF, but I'm just fukin slow at
doing things like this.

nop_90

lisp/scheme is very hard to wrap your head arround.

Most people who start to use these languages, do not start using them until they are "old" as in have a lot of

programming

  experience behind them.
Biggest reason is that to take advantage of the language, you have to know what the regular languages lack.

Things like continuations for a newbie are useless http://en.wikipedia.org/wiki/Continuation
And it took me like 6 months after i read about them to figure out a use for them.

Mac

 ros to rewrite code again are pretty much useless for a newbie. If he does not know how to make code to begin with, how can he make a

mac

 ro that can rewrite it ?

Probably there are just as many libraries if not more for lisp then most other languages. But again they are hard for newbies to understand. Hard to find etc.
And a newbie can not really harness the power of scheme/lisp

Anyway i am playing arround with continuations, and on my travels found the library and thought maybe might be useful for someone.

thedarkness

Hey NOP,

This is a form of data persistence right? In

PHP

  couldn't this be acheived through APC and to a lesser (slower) extent session variables and serialize/unserialize?

In C/C++ I imagine you could accomplish the same sort of thing using a master thread or app. and communicating with it using some sort of IPC or system wide mutexes/semaphores, etc. ?

Cheers,
td

nop_90

@darkness the whole point is to avoid threads. Probably it can be done the way u say, but it will be messy, prown to bug etc.
Anyway in a nutshell i will explain i will gloss over some of the details. But i will try and explain how continuation work.

simplest place to start is with

python

  generators

>>> def foo() :
...    yield 1
...    yield 2
...    yield 3
...   
>>> foo
<function foo at 0x84d5f44>

a=foo()
a
<generator object at 0x84dd2cc>

a.next()
1
a.next()
2

you have generator called foo
when i construct it and assign it to a
when i call a.next() it gives 1 , 2 etc
what is happening every time i next it runs it till next yield, and return that value in yield. when it hits yield it saves current state.

i will now show how done in scheme (u would not use this in real life, just shown like this for demo purpose)


(define cc '()) <--- cc is the state

(define (foo)
    (let ((i 0))
      (call/cc
      (lambda (k) <---- k is the continuation
        (set! cc k))) <--- save value of k in cc
      (set! i (+ i 7))
      i))


I load the above code into scheme
foo it the function everytime it start it take i and adds 7 to it. but i is local inside the function.

#;2> cc
() <--- cc has no value () is nil
#;3> (foo)
7 call foo 7 is returned
#;4> cc
#<procedure (a7138 . results79Applause> <-- notice value of cc now is a procedure this is the continuation
#;5> (cc '()) <--- call cc with a null arguement (using

mac

 ros i can get arround this, but want to keep simple, a continuation always takes 1 arg)
14
#;6> (cc '())
21
#;7> (cc '())
28
#;8> (cc '())
35
and it counts

using a

mac

 ro i can make the code look exactly

python

  (well with brackets ofcourse Applause)
but it go deeper then that.
I can pass the continuation back and forth etc.

in my case i am using it to emulate a state

mac

 hine.
so u will have a state

mac

 hine, but it will ap

pear

  to be linear.

thedarkness

So in a nutshell the advantages are:

1. It's fast

2. It's using local variables, not globals.

3. it's using the stack.

So the primary advantage over instantiating an object and maintaining state in that (with an equivalent call to a method) is speed?

A state

mac

 hine can be written without coroutines/continuations so I guess I need to understand what the real advantage is? Sorry if I'm a bit slow on the uptake brother.

Cheers,
td

nop_90

Basically what you said, and most importantly simplicity.
Probably a hand written state

mac

 hine would be quicker (if done in C/C++)
With a state

mac

 hine you have to take care of all the book keeping urself.

Lets say you had a function that searches for a element in a tree.
when it finds the element you want it returns.

But lets say you want to search for another element in tree from where u leave off .....
normally you would have to save the state before u search again.
But if u used a continuation, you would just call the function again, and it would resume from where it leave off.

They are hard to wrap ur head arround. After i read about them, it took me like 6 months to figger out what they are good for.
After they where invented it took like 10 years to find a use for them Applause

This article explains how they can be used in web framework
http://www.def

mac

 ro.org/ramblings/continuations-web.html


thedarkness

quote author=nop_90 link=topic=845.msg5888#msg5888 date=1206448185

Basically what you said, and most importantly simplicity.
Probably a hand written state

mac

 hine would be quicker (if done in C/C++)
With a state

mac

 hine you have to take care of all the book keeping urself.



This is what I would use for a state

mac

 hine, just a personal preference, not forcing it down anyones throat :-)

http://www.boost.org/libs/statechart/doc/index.html


quote author=nop_90 link=topic=845.msg5888#msg5888 date=1206448185

Lets say you had a function that searches for a element in a tree.
when it finds the element you want it returns.

But lets say you want to search for another element in tree from where u leave off .....
normally you would have to save the state before u search again.
But if u used a continuation, you would just call the function again, and it would resume from where it leave off.


OK, I think that I'm beginning to grok this, thanks.

quote author=nop_90 link=topic=845.msg5888#msg5888 date=1206448185

This article explains how they can be used in web framework
http://www.def

mac

 ro.org/ramblings/continuations-web.html



Thanks, I'll have a read.

Cheers,
td

nop_90

state

mac

 hines are great and in some cases you should use them (classic example is calculator)
where i am using continuations in is with multicurl.

before i used a state

mac

 hine

so i would have to do something like this

get-google: State1
get(http://www.google.com)
push curl onto multicurl

get-google-result: do some shit with the result


using continuations you can make it ap

pear

  linear.
get(http://www.google.com)
perform <--- this would be magic function that contains continuation adds it to multi etc
then when it returns do your shit

that way you have like 1/2 the ammount of code, and each part ap

pear

 s to be like a seperate thread

thedarkness

I fully understand where you are coming from now dude, interesting....

Cheers,
td


Perkiset's Place Home   Politics @ Perkiset's