[#5218] Ruby Book Eng tl, ch1 question — Jon Babcock <jon@...>
From: Jon Babcock <jon@kanji.com>
Thanks.
From: Jon Babcock <jon@kanji.com>
Ah, thanks, I think I get it, a slightly different nuance then.
From: Jon Babcock <jon@kanji.com>
'Because all of Ruby has been...' -> 'Because Ruby has been...'?
[#5221] better way to say 'recursive join' — Yasushi Shoji <yashi@...>
in [ruby-dev:6289], Shugo Maeda suggested better name for recursive
[#5240] Ruby for Win32/DOS — Dennis Newbold <dennisn@...>
Not all of us are blessed with the opportunity to be able to develop on
[#5254] problem: undefined method `size' for File — "葡ic Santonacci" <Eric.Santonacci@...>
Hi all,
HI,
[#5264] Re: problem: undefined method `size' for Fil e — Aleksi Niemel<aleksi.niemela@...>
matz critizes good solution argumenting with features lacking from some
[#5268] Proper ConditionVariable usage? — Aleksi Niemel<aleksi.niemela@...>
Abstract
On Wed, 04 Oct 2000 07:05:22 +0900, Aleksi Niemelwrote:
In message <20001004110040.A26666@xs4all.nl>
Hi,
[#5276] Re: Ruby Book Eng tl, ch1 question — schneik@...
[#5310] Errata for Ruby Book? — Jon Babcock <jon@...>
[#5318] Redefining super method as singleton? — Robert Feldt <feldt@...>
On Fri, 6 Oct 2000, Yukihiro Matsumoto wrote:
[#5329] Ruby vs PHP ? — "Valerio Bamberga" <bamberga@...>
Hi!
[#5331] Unit testing network code? — Hugh Sasse Staff Elec Eng <hgs@...>
Can someone give me pointers on how to Unit Test code that is run on
> I think maybe one would test each end on its own first, faking the
[#5335] string streams in Ruby? — Hugh Sasse Staff Elec Eng <hgs@...>
Is there any way, without going through "modifying the internals",
[#5346] Is Ruby "enough better"? — Gabriel Lima <Gabriel.Lima@...>
Hi.
[#5364] Allowing *ary's in the middle of a camma separated list — "Akinori MUSHA" <knu@...>
Hi,
Hi,
At Tue, 10 Oct 2000 14:17:24 +0900,
[#5404] Object.foo, setters and so on — "Hal E. Fulton" <hal9000@...>
OK, here is what I think I know.
At Wed, 11 Oct 2000 11:37:25 +0900,
Hi,
Hi,
Hi,
Hi,
[#5425] Ruby Book Eng. tl, 9.8.11 -- seishitsu ? — Jon Babcock <jon@...>
At Thu, 12 Oct 2000 03:49:46 +0900,
Thanks for the input.
At Thu, 12 Oct 2000 04:53:41 +0900,
At Thu, 12 Oct 2000 07:25:03 +0900,
oops, I didn't read this one before I went out for food..
At Thu, 12 Oct 2000 09:59:19 +0900,
[#5437] Editor recommandations? — "Chris Morris" <chrismo@...>
Any recommendations on editors for Ruby script on Windows?
[#5471] 2 ideas from Haskell — Mark Slagell <ms@...>
Do either of these interest anyone:
[#5479] Some newbye question — Davide Marchignoli <marchign@...>
I am reading the documentation I found about ruby but several points
[#5480] InstallShield version for Ruby soon... — andy@... (Andrew Hunt)
Okay folks,
[#5489] Regexp#matches — Aleksi Niemel<aleksi.niemela@...>
Would someone object aliasing matches for match in Regexp?
[#5505] Sorry, What is Ruby Book — Mansuriatus Shahrir Amir <chioque@...>
Sorry if this information is somewhere obvious. I just stumbled upon
[#5516] Re: Some newbye question — ts <decoux@...>
>>>>> "D" == Davide Marchignoli <marchign@di.unipi.it> writes:
Hi,
On Sat, 14 Oct 2000, Yukihiro Matsumoto wrote:
matz@zetabits.com (Yukihiro Matsumoto) writes:
Dave Thomas <Dave@thomases.com> wrote:
Hi,
> Proposal a and b have incompatibility. I'm not sure it's worth it.
>>>>> "Y" == Yukihiro Matsumoto <matz@zetabits.com> writes:
On Mon, 16 Oct 2000, ts wrote:
>>>>> "Y" == Yukihiro Matsumoto <matz@zetabits.com> writes:
[#5558] GC: malloc_memories — Mathieu Bouchard <matju@...>
Hi,
> |precipitate a new GC cycle if lots of resizing is done. My biggest
[#5570] Notes about GC — Mathieu Bouchard <matju@...>
[#5600] passing single or multiple strings. — Hugh Sasse Staff Elec Eng <hgs@...>
With multple assignments I can get nested arrays "shelled" (like peas)
In message "[ruby-talk:5600] passing single or multiple strings."
[#5603] debug command list in English — "Morris, Chris" <ChrisM@...>
I found this page which lists the interactive debugger commands ... anyone
[#5619] lint? — "Swit" <swit@...>
Is there something like lint for Ruby? I'd like to find NameErrors before
[#5705] Dynamic languages, SWOT ? — Hugh Sasse Staff Elec Eng <hgs@...>
There has been discussion on this list/group from time to time about
Hugh Sasse Staff Elec Eng wrote:
On Sat, 21 Oct 2000, Charles Hixson wrote:
[#5715] Help: sockets broken — jason petrone <jp@...>
I just compiled ruby 1.6.1 on an openbsd 2.6 machine(x86).
[#5716] Re: Array#insert — Aleksi Niemel<aleksi.niemela@...>
> From: jweirich@one.net [mailto:jweirich@one.net]
[#5727] String#slice surprise — "Guy N. Hurst" <gnhurst@...>
Hi,
Dave Thomas wrote:
[#5787] Shells and Ruby — "Dat Nguyen" <thucdat@...>
Hello all,
[#5850] Re: Array#insert rehashed — Aleksi Niemel<aleksi.niemela@...>
Dave asks for:
[#5862] succ but no pred? (& the MURKY award) — "Hal E. Fulton" <hal9000@...>
First of all, a serious question:
[#5873] Integer(String) weirdness for a ruby newbie — Stoned Elipot <Stoned.Elipot@...>
Hi,
[#5881] Q:what about "Programming Ruby"? — Gabriel Lima <Gabriel.Lima@...>
Hi to you all.
[#5882] [RFC] Towards a new synchronisation primitive — hipster <hipster@...4all.nl>
Hello fellow rubyists,
On Fri, 27 Oct 2000, hipster wrote:
[#5947] Hash.new {block} / Hash#default_proc{,_set} — "Brian F. Feldman" <green@...>
I've done very little testing, but I think I've successfully implemented the
[ruby-talk:5268] Proper ConditionVariable usage?
Abstract
In this rather longish mail I show two programs which either show a bug, a
feature, or author's misunderstanding of the condition variables. In the end
I propose few enhancements to current implementation.
The full story
How one should be using condition variables in concurrent programming? Few
examples that I don't understand what's going on, and probably highlight the
lack of concurrent programming knowledge of the author of this mail.
1)
I thought one thread (B) could wait for the variable and the other (A)
thread could signal when B could continue. Actually
ConditionVariable#broadcast made me think there could be unlimited amount of
waiters, which would be signalled to continue like this:
Notation:
\w thread
* creation of a thread
| execution of a thread
= wakeup of a thread
# termination of a thread
A B C D
* * *
| | |
cv.wait | |
cv.wait |
cv.wait
...
*
|
cv.broadcast
| = = =
| | | |
| # | |
| # |
| #
#
I'm suprised, however, by the following program. It creates threads B...
which immediately start to wait. I'd expect all threads will wait until the
cv is signalled, which won't happen, or until the program terminates.
Instead the waiting ends unexpectedly for every second thread.
require "thread"
Thread.abort_on_exception = true
def test_cv(th_count)
cv = ConditionVariable.new()
cm = Mutex.new
cm.lock
threads = []
th_count.times do |i|
th = Thread.start do
i_local = i
puts "#{i_local} waiting"
cv.wait(cm)
puts "#{i_local} waiting ends"
end
threads << th
end
puts "sleeping"
sleep 2
puts "cv.broadcast"
cv.broadcast
puts "final sleep"
sleep 2
puts "killing threads"
threads.each { |th| th.exit }
puts "threads killed", ""
end
10.times do |th_count|
test_cv(th_count)
end
I won't show the entire log, but the first 4 iterations which show the
points anyway:
ruby 1.6.1 (2000-10-02) [i686-linux]
sleeping
cv.broadcast
final sleep
killing threads
threads killed
0 waiting
sleeping
cv.broadcast
0 waiting ends
final sleep
killing threads
threads killed
0 waiting
1 waiting
1 waiting ends
sleeping
cv.broadcast
final sleep
killing threads
threads killed
0 waiting
1 waiting
1 waiting ends
2 waiting
sleeping
cv.broadcast
0 waiting ends
final sleep
killing threads
threads killed
2)
Then my second problem. I think the current ConditionVariable is inadequate
for anything but the most basic needs. For example if one wants to use it to
create synchronization points there will be surprises.
This example is borrowed from Dave&Andy's article about Mutual exclusions at
http://dev.rubycentral.com/articles/mutex.html. I modified it a bit to let
the "feature" show up. The trick is to get thread B's signal execute before
A will wait. For that I added couple lines of code to expose threads for
context switching, and run the test many times to be captured in the
deadlock eventually.
require 'thread'
Thread.abort_on_exception = true
def do_it
mutex = Mutex.new
cv = ConditionVariable.new
a = Thread.new {
c = rand(10)
d = c
mutex.synchronize {
puts "A: I have critical section, but will wait for cv"
cv.wait(mutex)
puts "A: I have critical section again! I rule!"
}
}
puts "(Later, back at the ranch...)"
b= Thread.new {
c = rand(10)
d = c
mutex.synchronize {
puts "B: Now I am critical, but am done with cv"
cv.signal
puts "B: I am still critical, finishing up"
}
}
a.join
b.join
end
loop { puts ""; do_it }
The logs from different platforms:
ruby 1.6.1 (2000-10-02) [i686-linux]
...
(Later, back at the ranch...)
B: Now I am critical, but am done with cv
B: I am still critical, finishing up
A: I have critical section, but will wait for cv
deadlock 0x401775fc: 2:0 - /home/niemela/lib/ruby/1.6/thread.rb:114
deadlock 0x401835a0: 2:8 (main) - cv_wait_deadlock.rb:32
cv_wait_deadlock.rb:32:in `join': Thread: deadlock (fatal)
from cv_wait_deadlock.rb:32:in `do_it'
from cv_wait_deadlock.rb:36
from cv_wait_deadlock.rb:36:in `loop'
from cv_wait_deadlock.rb:36
ruby 1.4.5 (2000-06-26) [i386-cygwin]
...
(Later, back at the ranch...)
B: Now I am critical, but am done with cv
B: I am still critical, finishing up
A: I have critical section, but will wait for cv
lib/thread.rb:114:deadlock 0xa052f40: 1:0
cv_wait_deadlock.rb:32:deadlock 0xa076028: 1:4 (main)
cv_wait_deadlock.rb:32:in `do_it': Thread: deadlock (fatal)
from cv_wait_deadlock.rb:36
from cv_wait_deadlock.rb:36:in `loop'
from cv_wait_deadlock.rb:36
===
Lastly I have few ideas for the future versions.
* I'd like to see a version of CV where signalling is queued
(optionally) so that cv.signal followed by later cv.wait
would not get lost. This solves the bug case 2 might be suffer.
* The first solution could be extended. The CV would count
signals, and CV#wait_for(n) is introduced. That would allow
one to write code like next example easily.
A B C
cv.wait_for(2) | |
cv.signal |
| |
= | cv.signal
| | |
I'm not sure how CV#broadcast should be done. Maybe it should
release all waiters.
Second extension could be for CV#signal(n) to pass a integer with
approximately same semantics as n.times{cv.signal} (done atomicly).
- Aleksi