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
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
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.
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.