Coroutines in D
Andrej Mitrovic
none at none.none
Tue May 3 11:06:38 PDT 2011
I'm trying to figure out how to use coroutines in D.
First, I think I've run into some kind of bug. I've followed this C++ example: http://www.subatomicglue.com/secret/coro/readme.html, and came up with this:
import std.stdio;
import core.thread;
void fiberFunc(size_t arg)
{
int i = 0;
foreach (x; 0 .. 1000)
{
writefln("fiber waiting (id = %d)", arg);
Fiber.yield();
}
foreach (x; 0 .. 1000)
{
writefln("fiber running (iter = %d id = %d)", ++i, arg);
Fiber.yield();
}
while (1)
{
writefln("fiber waiting (id = %d)", arg);
Fiber.yield();
}
}
void main()
{
Fiber[200] fibers;
foreach (ref fiber; fibers)
{
fiber = new Fiber(&fiberFunc);
}
while (true)
{
foreach (fiber; fibers)
{
fiber.call();
}
}
}
Only after I've translated the C++ example to D I've realized that fiberFunc actually takes an argument. But from what I can tell core.thread.Fiber never calls this function with any arguments. I have a hunch that "arg" ends up having an uninitialized garbage value, so it looks like this is a bug?
Ok, that put aside what I really want to emulate is this Python example of a coroutine (perhaps bearophile is familiar with this):
def coroutine(func):
def start(*args,**kwargs):
cr = func(*args,**kwargs)
cr.next()
return cr
return start
@coroutine
def unwrap_protocol(header='\x61',
footer='\x62',
dle='\xAB',
after_dle_func=lambda x: x,
target=None):
""" Simplified framing (protocol unwrapping)
co-routine.
"""
# Outer loop looking for a frame header
#
while True:
byte = (yield)
frame = ''
if byte == header:
# Capture the full frame
#
while True:
byte = (yield)
if byte == footer:
target.send(frame)
break
elif byte == dle:
byte = (yield)
frame += after_dle_func(byte)
else:
frame += byte
@coroutine
def frame_receiver():
""" A simple co-routine "sink" for receiving
full frames.
"""
while True:
frame = (yield)
print 'Got frame:', frame.encode('hex')
bytes = ''.join(chr(b) for b in
[0x70, 0x24,
0x61, 0x99, 0xAF, 0xD1, 0x62,
0x56, 0x62,
0x61, 0xAB, 0xAB, 0x14, 0x62,
0x7
])
unwrapper = unwrap_protocol(target=frame_receiver())
for byte in bytes:
unwrapper.send(byte)
This was taken from Eli's blog: http://eli.thegreenplace.net/2009/08/29/co-routines-as-an-alternative-to-state-machines/
I'm not seeing any way of yielding a value back from a Fiber or even sending it, so I don't see how I can use fibers to implement coroutines which send or return values. But I'm new to the concept so maybe I'm missing something obvious?
More information about the Digitalmars-d-learn
mailing list