[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Standard Queue Implementation and Thread Safety

Pete Kazmier

10/8/2003 6:45:00 PM

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
4 Answers

nobu.nokada

10/8/2003 10:37:00 PM

0

Hi,

At Thu, 9 Oct 2003 03:49:48 +0900,
Pete Kazmier wrote:
> 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.

--
Nobu Nakada

Joel VanderWerf

10/9/2003 5:03:00 AM

0

nobu.nokada@softhome.net wrote:
> Hi,
>
> At Thu, 9 Oct 2003 03:49:48 +0900,
> Pete Kazmier wrote:
>
>>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.

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?


nobu.nokada

10/9/2003 5:42:00 AM

0

Hi,

At Thu, 9 Oct 2003 14:03:13 +0900,
Joel VanderWerf wrote:
> >>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.
>
> 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

--
Nobu Nakada

Joel VanderWerf

10/9/2003 3:50:00 PM

0

nobu.nokada@softhome.net wrote:
> Hi,
>
> At Thu, 9 Oct 2003 14:03:13 +0900,
> Joel VanderWerf wrote:
...
>>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

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