Standard Queue Implementation and Thread Safety

P

Pete Kazmier

First the disclaimer: I'm a newbie to ruby :)

While looking at some of the standard libraries included in my ruby
distribution (1.8), I took particular interest in the thread.rb's
Queue implementation because I need to use it. However, I am not
certain that I understand why it is actually thread safe.

The implementation is essentially backed by an Array. Queue provides
synchronized push and pop methods (using Thread.critical), but methods
such as clear, length, and empty? are not synchronized. What happens
if one thread is in the middle of clearing the queue and then another
comes along to add/remove something from the queue? Why don't these
other methods need synchronization? Is Array thread-safe by default?

Thanks!
Pete
 
N

nobu.nokada

Hi,

At Thu, 9 Oct 2003 03:49:48 +0900,
Pete said:
The implementation is essentially backed by an Array. Queue provides
synchronized push and pop methods (using Thread.critical), but methods
such as clear, length, and empty? are not synchronized. What happens
if one thread is in the middle of clearing the queue and then another
comes along to add/remove something from the queue? Why don't these
other methods need synchronization? Is Array thread-safe by default?

Yes. Builtin methods (more accurately, not written in Ruby)
are thread-safe, unless GC runs. Since Array#empty? and
Array#length don't modify anything, and Array#clear just
releases but requires no memory, GC doesn't get run.
 
J

Joel VanderWerf

Hi,

At Thu, 9 Oct 2003 03:49:48 +0900,



Yes. Builtin methods (more accurately, not written in Ruby)
are thread-safe, unless GC runs. Since Array#empty? and
Array#length don't modify anything, and Array#clear just
releases but requires no memory, GC doesn't get run.

So Array#push is not thread-safe, but Queue#push is, right?

I understand that Array#push could provoke a GC, but why would GC cause
a context-switch?
 
N

nobu.nokada

Hi,

At Thu, 9 Oct 2003 14:03:13 +0900,
Joel said:
So Array#push is not thread-safe, but Queue#push is, right?

Array#push is thread-safe too.
I understand that Array#push could provoke a GC, but why would GC cause
a context-switch?

Though, finalizers could interrupt. Since they run in same
thread and critical section so context won't switch, but they
may try to modify the object.

$ ulimit -v 10240
$ ruby
array = Array.new(100, nil)
while array.size > 10
ObjectSpace.define_finalizer(Array.new(100000, nil)) {array.clear}
p array.push(nil).size
end
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
1
 
J

Joel VanderWerf

Hi,

At Thu, 9 Oct 2003 14:03:13 +0900,
Joel VanderWerf wrote: ...


Though, finalizers could interrupt. Since they run in same
thread and critical section so context won't switch, but they
may try to modify the object.

$ ulimit -v 10240
$ ruby
array = Array.new(100, nil)
while array.size > 10
ObjectSpace.define_finalizer(Array.new(100000, nil)) {array.clear}
p array.push(nil).size
end

Thanks, Nobu. I feel safer now, since I always regard finalizers with
suspicion, anyway.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,968
Messages
2,570,153
Members
46,699
Latest member
AnneRosen

Latest Threads

Top