Multiple threads calling the same function

Suppose we have several threads that call the same function:

def foo # do stuff ... end 100.times do |i| Thread.new do foo end end 

If two or more threads are inside foo , each of them has the same local variables within foo ?

This refers to the second question. Do threads have separate stack frames or share stack frames in a single process? In particular, when several threads each call foo and before foo returns whether there are several copies of foo on the stack, each with its own local variables, or is there only one copy of foo on the stack?

+7
source share
2 answers

Yes, they have the same variables. This is a key element of Threads and is great for read-only contexts, but if they are written to any of these variables, you need to use the Mutex and synchronize streams, so only one can change the variable at any time. Sometimes they can call a method that indirectly changes the data, so you need to know the system completely before deciding whether you need to synchronize or not.

As for your second question, if I understand what you are asking, they have separate stack frames, but they still use the same data in memory.

Clarification: in the following example, the local zip variable is shared by several threads, since it is defined in the current scope (threads do not change the scope), they simply start a separate parallel thread of execution in the current scope).

 zip = 42 t = Thread.new do zip += 1 end t.join puts zip # => 43 

Joining here saves me, but obviously there is no point in this thread if I keep it. It would be dangerous if I did the following:

 zip = 42 t = Thread.new do zip += 1 end zip += 1 puts zip # => either 43 or 44, who knows? 

This is because you basically have two threads that are simultaneously trying to change zip . This becomes noticeable when you access network resources or increase numbers, etc., as indicated above.

In the following example, however, the local zip variable is created inside a completely new area, so the two threads are not actually written to the same variable at the same time:

 def foo zip = 42 zip += 1 # => 43, in both threads end Thread.new do foo end foo 

There are two parallel stacks, each of which has its own local variables inside the foo method.

However, the following code is dangerous:

 @zip = 42 # somewhere else def foo @zip += 1 end Thread.new do foo end foo puts @zip # => either 43 or 44, who knows? 

This is because the @zip instance @zip is accessible outside the scope of the foo function, so both threads can access it at the same time.

These problems of "two streams that change the same data at the same time" are solved by carefully placed mutexes (locks) around sections of code that change a variable. Before creating threads, you need to create Mutex, because in the case of Mutex (by design), it is vital that both threads access the same Mutex to see if it is blocked or not.

 # somewhere else... @mutex = Mutex.new @zip = 42 def foo @mutex.synchronize do @foo += 1 end end Thread.new do foo end foo puts @zip # => 44, for sure! 

If the thread reaches the line Mutex#synchronize , it tries to lock the mutex. If successful, it enters the block and continues execution. As soon as the block ends, the mutex is unlocked again. If the mutex is already blocked, the thread waits until it becomes free again ... effectively, it is like a door through which only one person can go.

Hope this clarifies the situation.

+4
source

Local variables defined inside the method are not shared. But threads can access instance variables of the same object if they are in the stream scope.

For example:

 def foobar puts "Foo is defined!" if defined?(foo)=='local-variable' foo = 5 end 

will never put a string if called by multiple threads.

But synchronization requires a mutex because race conditions apply:

 foo = {bar:5} def foobar(value) value[:bar]+=5 end 15.times{|i| Thread.new{foobar foo}} 

After that, foo [: bar] may contain the value 35, since each call to foobar changes the value inside the hash, foo.

0
source

All Articles