e$B!!$5$5$@$G$9!#e(B
e$B!!e(BContinuation e$B$N$D$$$G$Ke(B Fiber
e$B$rF~$l$^$7$?!#6bMKF|$K$O=PMh$F$?$s$G$9e(B
e$B$,!"$b$m$b$m$"$C$F%3%_%C%H$,CY$/$J$C$F$7$^$$$^$7$?!#e(B
e$B!!$H$$$&$o$1$G!"3’MM$K$$$/$D$+$4AjCL$G$9!#$*$b$K!"L>A0$H5!G=$NOC$G$9!#9-e(B
e$B$/$40U8+$rD:$1$k$H9,$$$G$9!#e(B
e$B3+H/$7$?!Ve(BFibere$B!W$N35MW!'e(B
e$B!!e(BFiber
e$B$O%N%s%W%j%(%s%W%F%#%V$J%9%l%C%I$G!"e(BMicroThreade$B$H8@$o$l$?$j$7$^e(B
e$B$9!#e(BCoroutine
e$B$H8@$C$F$bNI$$$+$b$7$l$^$;$s!#%0%0$l$P$?$/$5$s>pJs$O=P$F$/e(B
e$B$k$H;W$$$^$9!#e(B
e$B!!=>Mh$N%9%l%C%I$G$N%3%s%F%-%9%H@Z$jBX$($N%?%$%_%s%0$O!"$*$b$K<!$N#3$D$Ge(B
e$B$7$?!#e(B
(1) Thread.pass e$B$r;H$C$?;~e(B
(2) IOe$BBT$A$K$J$C$?$H$-e(B
(3) e$B0lDj;~4V$+$+$C$?$H$-e(B
e$B!!e(BFiber
e$B$O!"$I$N>l9g$G$b@Z$jBX$o$j$^$;$s!#L@<(E*$K!V$I$N%U%!%$%P$X=hM}$re(B
e$B0$9$N$+!W$r<($5$J$1$l$P$J$j$^$;$s!#$=$N$?$a!"J#;($JF14|=hM}$r9T$o$J$$JBe(B
e$B9T=hM}$,2DG=$K$J$j$^$9!#$^$?!“e(BFiber e$B$N@8@.$O7ZNL$J$N$G!”?tK|e(B
Fiber e$B$N@8e(B
e$B@.$,?tIC$G=*$o$j$^$9!#B??t$N%(!<%8%’%s%H$r@8@.$7$F9T$&$h$&$J%7%_%e%l!<e(B
e$B%7%g%s$NMQES$K$O8~$/$+$b$7$l$^$;$s!J%M%$%F%#%V%9%l%C%I$rMxMQ$9$k$H!"e(BOS
e$B$N%9%l%C%I@[email protected]&$KG{$i$l$^$9!#e(B32bit Linux
e$B$@$H!"4hD%$C$F$b?t@i%9%l%C%Ie(B
e$B$,8B3&$K$J$j$^$9!K!#e(B
e$B!!$?$@$7!“e(BIOe$BBT$A$K$J$C$F$b=hM}$O@Z$jBX$o$i$J$$!J%V%m%C%/$9$k!K$?$a!”%M%Ce(B
e$B%H%o!<%/%W%m%0%i%_%s%0$K$O$*$=$i$/MxMQ$G$-$J$$$G$7$g$&!#7QB3%Y!<%9$N$J$se(B
e$B$H$+$+$s$H$+!"$@$C$?$iMxMQ2DG=$+$b$7$l$^$;$s$,!#e(B
e$B!!$J$*!“e(BFiber e$B$H$$$&!VL>A0!W$Oe(B Windows e$B$Ne(B API
e$B$KB8:_$7$^$9!#$3$l$,M3Mh!)e(B
CreateFiber() e$B$K$h$j!“e(BFiber e$B$r:n@.$7!“e(BSwitchToFiber()
e$B$G!”;XDj$N%U%!%$%Pe(B
e$B$K=hM}$r0$7$^$9!#85$Ne(B
Fibere$B!J0EL[$K@8@.$5$l$k!”%9%l%C%I$K$R$H$DIUB0$9$ke(B
e$B%U%!%$%P!K$XLa$i$J$$$G%U%!%$%P$N<B9T$,=*N;$7$?>l9g!”<+J,$N4D6-$G$O%W%m%0e(B
e$B%i%`$,Mn$A$^$7$?!#e(B
e$B!!8=::n$C$F$$?e(BFibere$B$N;H$$J}$O!"$3$s$J46$8$N;EMM$G$9!#$A$J$_$K!"<BAue(B
e$B$O!“MW$9$k$Ke(B matzruby e$B$Ne(B greenthread e$B$+$i!Ve(Bpreemptive
e$B$J%9%l%C%I@Z$jBXe(B
e$B$(!”$=$NB>F14|e(BAPIe$B!W$r0z$$$?$b$N$K$J$j$^$9!#e(B
-
e$B?7$7$$%U%!%$%P$r:n$C$F$_$ke(B
f = Fiber.new{
:ok
} -
e$B%U%!%$%Pe(B f e$B$X=hM}$r0$9e(B
f.pass
-
e$B%U%!%$%P$X!"CMIU$-$G=hM}$r0$9e(B
f.pass(value)
-
e$BJ#?t$N%U%!%$%P$G=hM}$r0\F0$7$"$&e(B
f2 = nil
f1 = Fiber.new{f2.pass; f2.pass}
f2 = Fiber.new{f1.pass; f1.pass}
f1.pass -
e$B8=:_F0$$$F$$$ke(B Fiber e$B$rCN$ke(B
Fiber.current # Thread.current e$B$HF1$8H/A[$G$9!#e(B
-
e$B:G8e$K=hM}$r0$7$?e(B Fiber e$B$rCN$ke(B
Fiber.prev e$B$b$7$/$Oe(B Fiber#prev
e$BMxMQNce(B
f0 = Fiber.current
f1 = Fiber.new{
p(Fiber.prev == f0) #=> true
}
f1.pass -
e$B0EL[$K@8@.$5$l$ke(B Fiber e$B$rCN$ke(B
e$B!!%9%l%C%I$,@8@.$5$l$k$H!“0EL[$N$&$A$K$R$H$De(B Fiber
e$B$,@8@.$5$l$k$3$H$K$Je(B
e$B$j$^$9!#$=$l$r!”$3$3$G$OJX59>ee(B root Fiber
e$B$H8@$&$3$H$K$7$^$9!#<B$O$^$@<Be(B
e$BAu$7$F$$$^$;$s$,!“e(BFiber.root
e$B$G$H$l$k$H$$$$$+$J!”$H;W$C$F$$$^$9!#$,!"e(B
e$B<h$C$F2?$9$k$N$+$O$h$/$o$+$j$^$;$s!#e(B
e$B!!$A$J$_$K!“e(Broot Fiber
e$B$,=*N;$7$?;~E@$G4XO”$E$1$i$l$F$$$k%9%l%C%I$O=*N;e(B
e$B$9$k$3$H$K$J$j$^$9!#e(B
- Fiber e$B=*N;;~$N=hM}$NN.$le(B
e$B!!$$$m$$$m9M$($F!"<!$N$h$&$K$9$k$h$&$K$7$^$7$?!#e(B
(a) e$B$^$:!"e(BFiber.prev e$B$Ke(B pass
(b) e$B$?$@$7!"e(BFiber.prev
e$B$,$9$G$K=*N;$7$F$$$k>l9g!"e(BFiber.root e$B$Xe(B pass
e$B!!e(BFiber e$B$KEO$9%V%m%C%/$NI>2ACM$O!"e(Bpass
e$B$GEO$k$3$H$K$J$j$^$9!#e(B
e$B!!$?$H$($P!"e(B
p Fiber.new{
:ok
}.pass #=> :ok
e$B$H$J$j$^$9!#e(B
e$B$4AjCL!'e(B
(1) e$B$=$b$=$b!"e(BRuby e$B$K$3$s$J5!G=$r2C$($F$$$$$G$9$+!)e(B
e$B!!$H$j$"$($:!"e(BGenerator e$B$OBgJQ=q$-$d$9$+$C$?$G$9!#e(B
(2) Fiber e$B$H$$$&L>A0$OE,Ev$G$7$g$&$+!)e(B
e$B!!e(BCoroutine
e$B$H$$$&L>A0$N$[$&$,$$$$$N$+$J$!!"$H$$$&5$$b$7$F$$$^$9!#e(BFiber
e$B$@$H!“e(BThread
e$B$K0z$-$:$i$l$F8m2r$,@8$8$k2DG=@-$,$”$k$+$b$7$l$^$;$s!#e(B
e$B$A$g$C$H$o$+$j$^$;$s!#e(B
(3) API e$BL>$OE,Ev$G$7$g$&$+!)e(B
e$B!!$H$$$&$+!“E,Ev$8$c$J$$$H;W$$$^$9!#e(BThread#pass e$B$H$NO"A[$Ge(B
Fiber#pass e$B$He(B
e$B$7$^$7$?$,!”!V5!G=$NO"A[$G!"%9%l%C%I$K0z$-$:$i$l$k!W!"!Ve(Bfib#pass
e$B$Ge(B fib
e$B$K=hM}$,0$k$H$O;W$$$E$i$$!W$J$I$NOC$,$"$k$H;W$$$^$9!#e(B
e$B!!$^$?!":G6a$N8@8l$K$"$k$h$&$Je(B suspend/resume e$B$K8BDj$7$?e(B API
e$B$K$9$k$N$be(B
e$B<j$+$b$7$l$^$;$s!Je(Bsemi-coroutinee$B!K!#5!G=$,8BDj$5$l$k$N$G!";H$$$d$9$$$+$ie(B
e$B$G$9!#$?$@!"8=:_$Ne(B Fiber e$B$N$[$&$,<+M3EY$O9b$$!Je(Bcallee/caller
e$B$N4X78$O!"e(B
e$B$J$$$b$N$H$7$FMxMQ2DG=!K$N$G!“e(Bsemi-coroutine
e$B$O%i%$%V%i%j<BAu$K$9$k!”$He(B
e$B$$$&$N$b<j$+$H;W$$$^$9!#e(B
e$B!!$G!"$$$m$$$m%a%=%C%IL>$r9M$($F$_$^$7$?!#e(B
class Fiber
alias start pass # e$B=i2s0J30$G$b;H$($F$$$$$b$N$+e(B (*)
alias restart pass # e$B=i2s$K;H$($F$$$$$b$N$+e(B
alias resume pass # suspend e$B$7$F$J$$$N$K;H$($F$$$$$b$N$+e(B
alias kick pass
alias call pass # call e$B$@$H!"BPEy$N4X78$8$c$J$$$C$]$$e(B
alias goto pass # fib.goto e$B$OJQ$@e(B
alias yield pass # e$B5!G=J6$i$o$7$/$J$$!)e(B
alias transit pass
def suspend *args # e$B8F$S=P$785$XLa$k!#e(Bsemi-coroutine /
e$B3N$+$KJXMxe(B
Fiber.prev.pass *args
end
end
(*)
e$B$7$+$7!"=i2s$+$I$&$+$r6hJL$9$k$?$a$K%U%i%0$r@_$1$k$N$bL5BL$C$]$$!#e(B
e$B!!$b$&!">e5-$NL>A0$rA4It%5%]!<%H$9$k!"$H$+$G$b$$$$$N$+$b$7$l$^$;$s!#$&!<e(B
e$B$s!"$d$C$Q$jBLL$+$J!#$h$/$o$+$j$^$;$s!#$I$&$7$^$7$g$&!#e(B
(4) e$B$b$C$H$[$+$Ne(B API
e$B!!B>$K$bI,MW$Je(B API e$B$C$FMW$k$G$7$g$&$+!#e(B
- e$BNce(B
e$B!!$h$/$"$j$=$&$J!"e(BProducer/Consumer e$B$NNc$G$9!J>e5-$Ne(B yield
e$B$Ne(B alias e$B$re(B
e$B;H$C$F$$$^$9!K!#e(B
producer/consumer sample
root = Fiber.current
consumer = nil
producer = Fiber.new{
10000.times{|e|
consumer.pass e
}
consumer.pass nil
}
consumer = Fiber.new{
while v = producer.yield
p v
end
}
producer.pass
e$B!!e(BFiber e$B$Ge(B Generator e$B$r:n$C$?Nc$G$9!J>e5-$Ne(B
suspend/resume e$B$r;H$C$F$$$^e(B
e$B$9!K!#e(BThreade$B!J$de(B
callcce$B!K$r;H$&$h$j!"$:$$$V$s$9$C$-$j$7$F$$$^$9!#e(B
Generator sample
class Generator
def initialize enum = nil, &block
@finished = false
@index = 0
@enum = enum
@block = block
@fib = if block_given?
Fiber.new{
yield self
@finished = true
}
else
Fiber.new{
enum.each{|e|
@e = e
@fib.suspend
}
@finished = true
}
end
@fib.start
end
def next?
!@finished
end
def next
raise “No element remained” if @finished
ret = @e
@index += 1
@fib.resume
ret
end
def end?
!self.next
end
def yield value
@e = value
@fib.suspend
end
def current
@e
end
def index
@index
end
alias pos index
def rewind
initialize(@enum, &@block) if @index.nonzero?
self
end
end
def show g
while g.next?
p g.next
end
end
show Generator.new([:a, :b, :c])
show Generator.new(1…3)
show Generator.new{|g|
g.yield 10
g.yield 20
g.yield 30
}