From: Suraj Kurapati on
Hi,

I am concerned about the lack of mutual exlusion in code listing
14.2 "Chat server using TCPServer and threads" on page 430 in "The
Well-Grounded Rubyist" book. That code goes something like this:

chatters = []

while ...
Thread.new(...) do |c|
chatters.each { ... }
chatters.push c
chatters.each { ... }
chatters.delete c
chatters.each { ... }
end
end

Multiple threads are spawned and each of them accesses the shared
resource (the chatters array) directly without mutual exclusion.

What happens when a thread inside chatters.each() gets descheduled
and another thread proceeds to add or delete an object to chatters?

Shouldn't there be a Mutex#synchronize call wrapping all access to
the chatters array?

Thanks for your consideration.
--
Posted via http://www.ruby-forum.com/.

From: Robert Klemme on
On 06.06.2010 07:29, Suraj Kurapati wrote:
> Hi,
>
> I am concerned about the lack of mutual exlusion in code listing
> 14.2 "Chat server using TCPServer and threads" on page 430 in "The
> Well-Grounded Rubyist" book. That code goes something like this:
>
> chatters = []
>
> while ...
> Thread.new(...) do |c|
> chatters.each { ... }
> chatters.push c
> chatters.each { ... }
> chatters.delete c
> chatters.each { ... }
> end
> end
>
> Multiple threads are spawned and each of them accesses the shared
> resource (the chatters array) directly without mutual exclusion.
>
> What happens when a thread inside chatters.each() gets descheduled
> and another thread proceeds to add or delete an object to chatters?
>
> Shouldn't there be a Mutex#synchronize call wrapping all access to
> the chatters array?

From what I see in your posting: yes.

Kind regards

robert

--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/
From: David A. Black on
Hi --

On Sun, 6 Jun 2010, Suraj Kurapati wrote:

> Hi,
>
> I am concerned about the lack of mutual exlusion in code listing
> 14.2 "Chat server using TCPServer and threads" on page 430 in "The
> Well-Grounded Rubyist" book. That code goes something like this:
>
> chatters = []
>
> while ...
> Thread.new(...) do |c|
> chatters.each { ... }
> chatters.push c
> chatters.each { ... }
> chatters.delete c
> chatters.each { ... }
> end
> end
>
> Multiple threads are spawned and each of them accesses the shared
> resource (the chatters array) directly without mutual exclusion.
>
> What happens when a thread inside chatters.each() gets descheduled
> and another thread proceeds to add or delete an object to chatters?
>
> Shouldn't there be a Mutex#synchronize call wrapping all access to
> the chatters array?

Probably. You're right that the code as it stands runs the risk of
modifying an array while iterating over it -- which, though it
probably wouldn't do any serious damage in this case, is (I think)
undefined as to its results in Ruby, and in any case is something I
don't (consciously :-) advocate doing.


David

--
David A. Black, Senior Developer, Cyrus Innovation Inc.

THE Ruby training with Black/Brown/McAnally
COMPLEAT Coming to Chicago area, June 18-19, 2010!
RUBYIST http://www.compleatrubyist.com

From: Keith Johnston on
"Probably"? If by "probably" you mean "yes".

Won't do any "serious damage"? Since when is producing the wrong
answer not "serious" in programming?

You would be much better off making a frank admission the mistake. We
all know cognitive dissonance can be disorienting, but that's no
excuse to indulge it.