[1.9] Queue$B$N(Bfairness

Queuee$B$Ne(Bfairnesse$B$OI,MW$G$7$g$&$+!#e(B

e$B$3$3$Ge(B"fairness"e$B$G0U?^$7$F$$$k$N$O!"e(BQueue#pope$B$GJ#?t$N%9%l%C%I$,BT$C$F$$e(B
e$B$k>l9g$K!“0lHVD9$/BT$C$F$$$k%9%l%C%I$+$i=g$K@)8f$rEO$5$l$k$3$H!”$G$9!#e(B

e$B$3$N0UL#$G$O!"e(B1.8e$B$Ne(BQueuee$B$Oe(Bfaire$B$G!"Nc$($P0J2<$N%9%/%j%W%H$rAv$i$;$k$H!"e(B
e$B>o$Ke(B[:go, :first]e$B$HI=<($5$l$^$9!#e(B

fair-but-slow-queue-for-1.9.diff · GitHub

create_waiter = lambda { |name, command|
t = Thread.new {
p [command.pop, name]
}
Thread.pass until t.status == ‘sleep’
t
}

50.times do
command = Queue.new

create 3 waiters, and…

create_waiter.call(:first, command)
create_waiter.call(:second, command)
create_waiter.call(:third, command)

and pushes a command.

command.push(:go)

then try to consume the command by a subsequent thread

Thread.new {
p [command.pop, :LATER]
}
end

e$B$3$l$KBP$7e(B1.9e$B$G$O!“e(BQueuee$B$,e(Bfaire$B$G$O$J$/$J$C$?$?$a!”;~!9e(B[:go,
:LATER]e$B$J$Ie(B
e$B$HI=<($5$l$^$9!#e(B

e$B@5D>$J$H$3$m!"e(BRubye$B$G$Oe(Bprimitivee$B$Ne(BMutex#locke$B$,e(Bfaire$B$G$O$J$$!J4V0c$C$F$$$?e(B
e$B$i;XE&$r$*4j$$$7$^$9!K$3$H$+$i!“e(BQueuee$B$@$1$,$s$P$C$F$b$M!”$H$$$&5$$O$7$^e(B
e$B$9!#$7$+$7e(B1.9e$B$Ne(BQueuee$B$b!“7k9=@K$7$$$H$3$m$^$Ge(Bfaire$B$J$N$G!”$&$^$$2r7hK!$,$"e(B
e$B$l$P!#!#!#C/$+;W$$$D$-$^$;$s$+!#e(B

e$B$H$j$“$($:e(B1.8e$B$Ne(BQueuee$B$r%9%l%C%I%9%1%8%e!<%i$b$I$-$K;H$C$F$$$k?M$O!”$b$7e(B
e$B%O%^$C$?$ie(Bfairnesse$B$r5?$C$F$_$k$H$h$$$+$b$7$l$^$;$s!#;d$NE57?E*$J;H$$J}e(B
e$B$O!"0J2<$G$7$?!#e(B

gist:430066 · GitHub

require ‘thread’

q = Queue.new
t1 = Thread.new {
p [:t1, q.pop]
q.push(:t1)
}

q.push(:main)
p [:main, q.pop]

e$B$A$J$$Ke(BJRubye$B$be(Bunfaire$B!Je(B1.8e$B$b!K$J$s$G$9$,!“e(B1.9e$B$H$O0[$J$j!”!Ve(Bmain
threade$B$@e(B
e$B$1$O3d$j9~$
$G$-$k!W$H$$$&>uBV$K$J$C$F$$$^$9!#:G=i$N%5%s%W%k$OLdBj$J$/e(B
e$BF0$-$^$9$,!":G8e$N%d%D$O%@%a!#$A$J$_$K<BAu$Oe(Bfastthreade$B:n<T$Ne(B@mentalguye$B!#e(B