3

I have a variable that is accessed from two threads. Do I need to use mutex when one thread is modifying it while the other is only reading it?

My understanding is that mutex is needed if both threads are writing to the same variable, but not for the case above as write happens only from one thread.

sawa
  • 165,429
  • 45
  • 277
  • 381
GoT
  • 530
  • 1
  • 13
  • 35
  • Should be fine without mutex – Wand Maker Jan 28 '16 at 08:30
  • 3
    @WandMaker that is not correct. Imagine the variable containing a hash with two keys. The scenario: thread1 starts to modify a hash and modifies _only the first value_. Then context switches and thread2 starts to read. The value of the variable, read by thread2 is in inconsistent state. – Aleksei Matiushkin Jan 28 '16 at 08:32
  • @mudasobwa - Yeah, you have a point. May be `Queue` class should be used instead of mutex if it is really producer-consumer scenario. – Wand Maker Jan 28 '16 at 08:35
  • @mudasobwa what does inconsistent state mean? If context switch happens during a write, will the read value be a outdated value or will it be a wrong/invalid value? – GoT Jan 28 '16 at 19:14

2 Answers2

3

The library concurrent-ruby has a lot of primitives for concurrency.

For example, it has a thread-safe implementation Hash.

There are also classes for doing immutable values and thread-safe variables.

For example:

require 'concurrent'

variable = { n: 0 }

lock = Concurrent::ReadWriteLock.new

t1 = Thread.new do 
  30.times { 
    lock.with_write_lock { 
      variable[:n] =  variable[:n] + 1
      puts 'Writer 1 wrote'
    } 
    sleep 0.5
  }
end

t2 = Thread.new do
  30.times { 
    lock.with_write_lock { 
      variable[:n] =  variable[:n] + 1
      puts 'Writer 2 wrote'
    } 
    sleep 0.5
  }
end

t3 = Thread.new do
  20.times { 
    lock.with_read_lock { puts 'Reading', variable[:n] }
    sleep 1
  }

end

t1.join
t2.join
t3.join
Jesper
  • 4,535
  • 2
  • 22
  • 34
3

Unless the method modifying the object is atomic, you need mutex. In fact, even write is not atomic in Ruby. Cf. Read and write file atomically.

Community
  • 1
  • 1
sawa
  • 165,429
  • 45
  • 277
  • 381