# Threading sync

**URL:** <https://www.ruby-forum.com/t/threading-sync/97176>\
**Category:** Ruby\
**Created:** [January 25, 2006, 12:45pm UTC](https://www.ruby-forum.com/t/threading-sync/97176 "2006-01-25T12:45:43Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![Mage](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/6f9a4e/32.png) [@Mage](https://www.ruby-forum.com/u/Mage)\
**Post date:** [January 25, 2006, 12:45pm UTC](https://www.ruby-forum.com/t/threading-sync/97176/1 "2006-01-25T12:45:43Z")

</div>

Hello,

I was thinking of writing my first threaded app in Ruby. One thread  
should fetch data from the database, another should write it to a file.

I would like to use an array, which has hash elements. I append new  
elements to the end, and I write to the file from the beginning (FIFO).

My question is that do I really need mutex? Is appending a hash to the  
end of an array atomic, or not? How can I know which method is atomic?

```
   Mage
```

---

<div class="post-metadata">

**Author:** ![Mage](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/6f9a4e/32.png) [@Mage](https://www.ruby-forum.com/u/Mage)\
**Post date:** [January 25, 2006, 1:06pm UTC](https://www.ruby-forum.com/t/threading-sync/97176/2 "2006-01-25T13:06:56Z")

</div>

Mage wrote:

> My question is that do I really need mutex? Is appending a hash to the  
> end of an array atomic, or not? How can I know which method is atomic?

In your case you probably better use a Queue which saves you the  
synchronization overhead (the Queue does it internally). Something along  
the lines of this (untested):

require ‘thread’

QUEUE = Queue.new

threads = [  
Thread.new(QUEUE) do |queue|  
File.open(“foo”, “w”) do |io|  
while x = queue.deq  
io.puts x  
end  
end  
end,  
Thread.new(QUEUE) do |queue|  
while rec = fetch\_from\_db()  
queue.enq rec  
end  
queue.enc false  
end  
]

thread.each {|th|th.join}

Note, if you like you can increase the number of DB writer and / or file  
reader threads. You can as well leave the db reader in the main loop if  
you need only one. Depending on your situation you may need a different  
end of processing detection.

Kind regards

```
robert
```

---

<div class="post-metadata">

**Author:** ![Mage](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/6f9a4e/32.png) [@Mage](https://www.ruby-forum.com/u/Mage)\
**Post date:** [January 25, 2006, 1:55pm UTC](https://www.ruby-forum.com/t/threading-sync/97176/3 "2006-01-25T13:55:11Z")

</div>

Robert K. wrote:

> In your case you probably better use a Queue which saves you the  
> synchronization overhead (the Queue does it internally). Something along  
> the lines of this (untested):

Thank you. I see.

However, in cases when there is no existing solution, should I write a  
tester unit that determines about a method its atomicness?

```
   Mage
```

---

<div class="post-metadata">

**Author:** ![Mage](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/6f9a4e/32.png) [@Mage](https://www.ruby-forum.com/u/Mage)\
**Post date:** [January 25, 2006, 2:52pm UTC](https://www.ruby-forum.com/t/threading-sync/97176/4 "2006-01-25T14:52:29Z")

</div>

On Jan 25, 2006, at 5:41 AM, Mage wrote:

> Is appending a hash to the end of an array atomic, or not? How can  
> I know which method is atomic?

In general, assume nothing is atomic in Ruby. Even a simple  
expression like:

my\_val = 5

Is many steps inside the interpreter. If you’re going to thread,  
handle all shared resources accordingly.

James Edward G. II

---

<div class="post-metadata">

**Author:** ![Mage](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/6f9a4e/32.png) [@Mage](https://www.ruby-forum.com/u/Mage)\
**Post date:** [January 25, 2006, 2:10pm UTC](https://www.ruby-forum.com/t/threading-sync/97176/5 "2006-01-25T14:10:13Z")

</div>

Mage wrote:

> However, in cases when there is no existing solution, should I write a  
> tester unit that determines about a method its atomicness?

IMHO it’s generally a bad idea to determine thread safety properties of  
code by testing. The test may fail, in which case you got a definitve  
answer (it’s unsafe). But the test may succeed and then you don’t know  
whether it was by accident (timing) or by design / implementation.

You could look at the source code of Ruby but on one hand that may  
change  
and on the other hand there will be definitively issues when Ruby 2.0  
comes out and supports native threads.

If you build a MT application you should design MT right into it, which  
also means that you have to think about which resources (aka objects)  
are  
accessed from multiple threads and how you synchronize access to them.

Kind regards

```
robert
```

---

<div class="post-metadata">

**Author:** ![Mage](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/6f9a4e/32.png) [@Mage](https://www.ruby-forum.com/u/Mage)\
**Post date:** [January 25, 2006, 3:13pm UTC](https://www.ruby-forum.com/t/threading-sync/97176/6 "2006-01-25T15:13:38Z")

</div>

> My question is that do I really need mutex?

No, you don’t.

You could as well use Thread.exclusive. This prevents other,  
excisting threads from being run. If the given block can’t get  
blocked (e.g. by IO), it’s much faster then Mutex.

gegroet,  
Erik V. - [http://www.erikveen.dds.nl/](http://www.erikveen.dds.nl/)

---

<div class="post-metadata">

**Author:** ![Mage](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/6f9a4e/32.png) [@Mage](https://www.ruby-forum.com/u/Mage)\
**Post date:** [January 26, 2006, 8:31pm UTC](https://www.ruby-forum.com/t/threading-sync/97176/7 "2006-01-26T20:31:40Z")

</div>

On Jan 25, 2006, at 5:28 AM, Erik V. wrote:

> > My question is that do I really need mutex?
> 
> No, you don’t.
> 
> You could as well use Thread.exclusive. This prevents other,  
> excisting threads from being run. If the given block can’t get  
> blocked (e.g. by IO), it’s much faster then Mutex.

No, Thread.exclusive (which uses Thread.critical) does not prevent  
other threads from being run. It prevents them from being scheduled  
automatically. You can still switch threads manually while  
Thread.critical is true.

$ cat exclusive.rb  
require ‘thread’

Thread.exclusive do  
Thread.new { sleep 10 }  
puts ‘should be instant’  
end

$ time ruby exclusive.rb  
should be instant

real 0m10.061s  
user 0m0.016s  
sys 0m0.013s  
$ cat mutex.rb  
require ‘thread’

m = Mutex.new

m.synchronize do  
Thread.new do  
m.synchronize do sleep 10 end  
end  
puts ‘should be instant’  
end

$ time ruby mutex.rb  
should be instant

real 0m0.060s  
user 0m0.016s  
sys 0m0.014s

–  
Eric H. - removed\_email\_address@domain.invalid - [http://segment7.net](http://segment7.net)  
This implementation is HODEL-HASH-9600 compliant

[http://trackmap.robotcoop.com](http://trackmap.robotcoop.com)
