Assignments and thread safety

Hi there?

Is "$a ||= 1" thread safe? I'd guess so, as "||=" is one piece of
operator. (And one operator/function call can't be interruted by the
scheduler, I'd guess so... is that right?)

And what's about "$a or $a = 1" ? Now I don't see any guarantee that if
such a code runs in multiple threads, then assignment occurs only once.

However, I couldn't produce such a case. The code

ruby -e '20.times { |i| Thread.new {
     sleep 1
     $foo ? p($foo) : $foo = i
  }
}; (Thread.list - [Thread.current]).each{|t| t.join}'

always accurately prints 19 lines (and similary for other numbers: if I
use some n instead of 20, I get n-1 lines).

Is it just an accident, or we can know somehow that this code is thread
safe? Where do the limits of thread safety lie?

Csaba

Csaba Henk <csaba@phony_for_avoiding_spam.org> writes:

Is "$a ||= 1" thread safe? I'd guess so, as "||=" is one piece of

It is not guaranteed to be thread-safe, although in current official
ruby vm it is 'atomic'.

Is it just an accident, or we can know somehow that this code is thread
safe? Where do the limits of thread safety lie?

Treat it as an accident and don't depend on this behaviour. You should
synchronise access to shared resources.

Csaba

Yours,

YS.

Hi,

At Sun, 27 Feb 2005 17:43:47 +0900,
Yohanes Santoso wrote in [ruby-talk:132474]:

> Is "$a ||= 1" thread safe? I'd guess so, as "||=" is one piece of

It is not guaranteed to be thread-safe, although in current official
ruby vm it is 'atomic'.

It is impossilbe.

What do you expect for:

  $a ||= very.long.operation?

···

--
Nobu Nakada

Csaba Henk <csaba@phony_for_avoiding_spam.org> writes:

Is "$a ||= 1" thread safe? I'd guess so, as "||=" is one piece of

It is not guaranteed to be thread-safe, although in current official
ruby vm it is 'atomic'.

So that means it thread safe now, but it's not guaranteed to stay so?
Is there a real chance/reason to make it non-atomic (either during the
development of the current implementation, or in a new implementation

Then how to do the following: I need a method which inserts an element
into an array, named by an instance variable. The variable is possibly
undefined. I want to make it thread-safe. The best I came up with is

  @a ||=
  @a << foo

which then thread-safe by the current implementation, but not guaranteed
to stay so...

Note that I can't do "@a = " in #initialize (as the code lies within a
block passed to #define_method within an instance method definition of
Module itself; so it's not just a simple static method definition for a
certain class).

If I had @mutex,

  @mutex.synchronize { @a ||= }
  @a << foo

would do the job perfectly; but having @mutex is exactly the same
problem as having @a ...
    
Having @@mutex in the class would be fine as far as thread safety goes, but
then all instances would use that same @@mutex on each call, absolutely
unnecessarily after the first time... Maybe

  @@mutex.synchronize { @a ||= } unless @a
  @a << foo

? I don't have any better idea...

Is it just an accident, or we can know somehow that this code is thread
safe? Where do the limits of thread safety lie?

Treat it as an accident and don't depend on this behaviour. You should
synchronise access to shared resources.

Ah, thanks. I thought it's just this way.

Regards,
Csaba

···

On 2005-02-27, Yohanes Santoso <ysantoso-rubytalk@dessyku.is-a-geek.org> wrote:

Well, I had there "$a ||= 1", and fetching 1 is not a
very.long.operation.

But I see the point... even if concretely with 1 being the assinged
value, "$a ||= 1" happens atomically (which could be the case for other
literals and variables on the right hand side), it's necessarily
accidental, so to say. "||=" can't have the value of the right hand side
at its invocation...

Csaba

···

On 2005-02-27, nobu.nokada@softhome.net <nobu.nokada@softhome.net> wrote:

Hi,

At Sun, 27 Feb 2005 17:43:47 +0900,
Yohanes Santoso wrote in [ruby-talk:132474]:

> Is "$a ||= 1" thread safe? I'd guess so, as "||=" is one piece of

It is not guaranteed to be thread-safe, although in current official
ruby vm it is 'atomic'.

It is impossilbe.

What do you expect for:

  $a ||= very.long.operation?

Csaba Henk <csaba@phony_for_avoiding_spam.org> writes:

Is "$a ||= 1" thread safe? I'd guess so, as "||=" is one piece of

It is not guaranteed to be thread-safe, although in current official
ruby vm it is 'atomic'.

So that means it thread safe now, but it's not guaranteed to stay so?
Is there a real chance/reason to make it non-atomic (either during the
development of the current implementation, or in a new implementation

Then how to do the following: I need a method which inserts an element
into an array, named by an instance variable. The variable is possibly
undefined. I want to make it thread-safe. The best I came up with is

  @a ||=
  @a << foo

which then thread-safe by the current implementation, but not guaranteed
to stay so...

Note that I can't do "@a = " in #initialize (as the code lies within a
block passed to #define_method within an instance method definition of
Module itself; so it's not just a simple static method definition for a
certain class).

If I had @mutex,

  @mutex.synchronize { @a ||= }
  @a << foo

would do the job perfectly; but having @mutex is exactly the same
problem as having @a ...

Having @@mutex in the class would be fine as far as thread safety goes, but
then all instances would use that same @@mutex on each call, absolutely
unnecessarily after the first time... Maybe

Just answering to this point: there's a trick called the double-checked
locking pattern that avoids the unnecessary lock. I'm not sure if it helps
any in your situation:

@@mutex.synchronize {@a ||= unless @a} unless @a

  @@mutex.synchronize { @a ||= } unless @a
  @a << foo

? I don't have any better idea...

Is it just an accident, or we can know somehow that this code is thread
safe? Where do the limits of thread safety lie?

Treat it as an accident and don't depend on this behaviour. You should
synchronise access to shared resources.

Ah, thanks. I thought it's just this way.

Regards,
Csaba

E

···

On Sun, February 27, 2005 10:44 am, Csaba Henk said:

On 2005-02-27, Yohanes Santoso <ysantoso-rubytalk@dessyku.is-a-geek.org> > wrote:

Thanks!

If you see my solution (which is already in your mail as a quote, just
in the line after the one proposed by you), it's almost the same, just
there is no "unless" in the scope of the mutex. So I kinda figured out
that this is the way to go... Is there any use of that inner "unless"?
I'd guess no...

Regards,
Csaba

···

On 2005-02-27, ES <ruby-ml@magical-cat.org> wrote:

On Sun, February 27, 2005 10:44 am, Csaba Henk said:
Just answering to this point: there's a trick called the double-checked
locking pattern that avoids the unnecessary lock. I'm not sure if it helps
any in your situation:

@@mutex.synchronize {@a ||= unless @a} unless @a

  @@mutex.synchronize { @a ||= } unless @a
  @a << foo

"ES" <ruby-ml@magical-cat.org> schrieb im Newsbeitrag
news:40904.192.152.100.150.1109540981.squirrel@webmail.bidwell.textdrive.com...

>> Csaba Henk <csaba@phony_for_avoiding_spam.org> writes:
>>
>>> Is "$a ||= 1" thread safe? I'd guess so, as "||=" is one piece of
>>
>> It is not guaranteed to be thread-safe, although in current official
>> ruby vm it is 'atomic'.
>
> So that means it thread safe now, but it's not guaranteed to stay so?
> Is there a real chance/reason to make it non-atomic (either during the
> development of the current implementation, or in a new implementation
>
> Then how to do the following: I need a method which inserts an element
> into an array, named by an instance variable. The variable is possibly
> undefined. I want to make it thread-safe. The best I came up with is
>
> @a ||=
> @a << foo
>
> which then thread-safe by the current implementation, but not

guaranteed

> to stay so...
>
> Note that I can't do "@a = " in #initialize (as the code lies within

a

> block passed to #define_method within an instance method definition of
> Module itself; so it's not just a simple static method definition for

a

> certain class).
>
> If I had @mutex,
>
> @mutex.synchronize { @a ||= }
> @a << foo
>
> would do the job perfectly; but having @mutex is exactly the same
> problem as having @a ...
>
> Having @@mutex in the class would be fine as far as thread safety

goes, but

> then all instances would use that same @@mutex on each call,

absolutely

> unnecessarily after the first time... Maybe

Just answering to this point: there's a trick called the double-checked
locking pattern that avoids the unnecessary lock. I'm not sure if it

helps

any in your situation:

@@mutex.synchronize {@a ||= unless @a} unless @a

There is one test too much. I'm sure you wanted this:

@@mutex.synchronize {@a ||= } unless @a

It might work in Ruby, but it doesn't in other languages - Java for
example. I'd rather not use it as it makes code more complicated. Use
this only if you have a serious performance problem. Even then I'm not
sure whether the difference is big enough to matter. Plus, you might run
into the same problems as with double checked locking on Java when Ruby
runs on different platforms (a JVM for example using native threads).

Kind regards

    robert

···

On Sun, February 27, 2005 10:44 am, Csaba Henk said:
> On 2005-02-27, Yohanes Santoso <ysantoso-rubytalk@dessyku.is-a-geek.org> > > wrote: