多个线程调用同一个功能(Multiple threads calling the same func

2019-07-29 06:55发布

假设我们有多个线程调用所有相同功能:

def foo 
  # do stuff ...
end

100.times do |i|
  Thread.new do
    foo
  end
end

如果两个或多个线程目前的内部foo ,难道他们每一股份在同一局部变量foo

这涉及到我的第二个问题。 在线程拥有独立的堆栈帧,或者他们共享一个进程中的栈帧? 具体来说,当多个线程调用每一个foo之前foo的回报,是有多个副本foo在栈中,每个都有自己的局部变量,或者是有只有一个副本foo在堆栈上?

Answer 1:

是的,它们共享相同的变量。 这是线程的一个关键因素,是罚款只读语境,但如果他们写的任何这些变量,你需要使用一个Mutexsynchronize线程,所以只有一个可以在任何给定的时间内改变一个变量。 有时,他们可能会调用这也间接改变数据的方法,所以你需要知道你的决定前充分,如果你需要同步或不系统。

至于你的第二个问题,如果我理解你的要求,他们有独立的堆栈帧, 他们仍然都在内存共享相同的数据。

的澄清,在下面的示例中,本地变量zip 多线程共享的,因为它是在当前范围(线程不改变的范围,它们只是开始一个单独的执行,并行线程在当前范围)所定义。

zip = 42

t = Thread.new do
  zip += 1
end

t.join

puts zip # => 43

这里的加盟为我节省了,但显然有一个在线程没有意义可言,如果我继续存在。 如果我是做以下这将是危险的:

zip = 42

t = Thread.new do
  zip += 1
end

zip += 1

puts zip # => either 43 or 44, who knows?

那是因为你基本上有两个线程都试图修改zip在同一时间。 这将成为明显的,当你访问网络资源,或递增的数字等,如上述。

在下面的示例,然而,局部变量zip被内部的一个全新的范围内创建,所以这两个线程不实际写入在同一时间同一变量:

def foo
  zip = 42
  zip += 1 # => 43, in both threads
end

Thread.new do
  foo
end

foo

有管理两个平行叠层,每个跟了进去自己的局部变量foo方法。

下面的代码,但是,是危险的:

@zip = 42 # somewhere else

def foo
  @zip += 1
end

Thread.new do
  foo
end

foo

puts @zip # => either 43 or 44, who knows?

这是因为实例变量@zip是范围的外部访问foo功能,所以两个线程可以在同一时间访问它。

“两个线程同时改变相同的数据”的这些问题通过使用小心放置互斥(锁)的代码,能够改变可变区段周围解决。 在创建线程之前互斥必须创建,因为在互斥锁的情况下,(设计)至关重要的是,两个线程访问同一个互斥体,才能知道它是否锁止。

# 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!

如果在执行流到达Mutex#synchronize线,它试图锁定互斥。 如果成功的话,它进入块并继续执行。 一旦块完成,互斥量被释放一次。 如果互斥已经锁定,该线程等待,直到它变成重获自由......有效就好像只有一个人可以一次走过一扇门。

我希望这将清除的东西了。



Answer 2:

局部变量,所述方法中定义的,不被共享。 但它有可能对线程访问同一个对象的实例变量,如果它是在线程块的范围。

例如:

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

永远不会把字符串,如果所谓的由多个线程。

但下面需要同步互斥,因为比赛条件:

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

在此之后,富[:巴]可能可能包含35值,因为foobar的的每一个电话,改变了哈希,FOO内的值。



文章来源: Multiple threads calling the same function