Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When do you need to pass arguments to `Thread.new`?

Local variables defined outside of a thread seem to be visible from inside so that the following two uses of Thread.new seem to be the same:

a = :foo
Thread.new{puts a} # => :foo
Thread.new(a){|a| puts a} # => :foo

The document gives the example:

arr = []
a, b, c = 1, 2, 3
Thread.new(a,b,c){|d, e, f| arr << d << e << f}.join
arr #=> [1, 2, 3]

but since a, b, c are visible from inside of the created thread, this should also be the same as:

arr = []
a, b, c = 1, 2, 3
Thread.new{d, e, f = a, b, c; arr << d << e << f}.join
arr #=> [1, 2, 3]

Is there any difference? When do you need to pass local variables as arguments to Thread.new?

like image 679
sawa Avatar asked May 25 '13 02:05

sawa


People also ask

How do you pass an argument to a thread function?

You can only pass a single argument to the function that you are calling in the new thread. Create a struct to hold both of the values and send the address of the struct.

Can we pass parameters to thread?

The first way we can send a parameter to a thread is simply providing it to our Runnable or Callable in their constructor.

What is the last argument passed to the pthread_create () function?

The last parameter of pthread_create() is passed as the argument to the function, whereas the return value is passed using pthread_exit() and pthread_join() .


2 Answers

When you pass a variable into a thread like that, then the thread makes a local copy of the variable and uses it, so modifications to it do not affect the variable outside of the thread you passed in

a = "foo"
Thread.new{ a = "new"}
p a # => "new"
Thread.new(a){|d| d = "old"} 
p a # => "new"
p d # => undefined
like image 70
concept47 Avatar answered Oct 19 '22 19:10

concept47


I think I hit the actual problem. With a code like this:

    sock = Socket.unix_server_socket(SOCK)
    sock.listen 10
    while conn = sock.accept do
        io, address = conn
        STDERR.puts "#{io.fileno}: Accepted connection from '#{address}'"
        Thread.new{ serve io }
    end

it appears to work when accepting few connections. The problem comes when accepting connections quickly one after another. The update to local variable io will be reflected in multiple concurrent threads unless passed as argument to Thread.new

like image 1
Vincent Vega Avatar answered Oct 19 '22 20:10

Vincent Vega