尝试和未能引入竞争条件的简单脚本

时间:2016-11-06 21:09:47

标签: ruby multithreading concurrency parallel-processing thread-safety

我试图理解并发性与并行性。

我的理解是,当线程依赖于共享状态时,并发性具有竞争条件。例如,如果N个线程同时从共享输入数组弹出并推送到共享输出数组,则存在输出数组将包含重复项的风险。

我知道Ruby解释器是为防止这种行为而设计的,但从概念上讲,我是否正确理解可能性仍存在,如果需要完全原子性,还应采取额外的预防措施?

我试图创建一个显示竞争条件但无法做到的示例。我想知道是否有一些简单的代码来创建竞争条件以显示并发的限制(vs并行性,据我所知是原子的)。

这是尝试 - 这需要大约4秒钟才能运行,并在我的i5处理器上使用大约25%的CPU。没有多少记忆。

module AtomicityTestWithConcurrentThreadsAndGlobalVariables

  # parameters
  Thread_count = 10_000
  Method_calls_per_thread = 10
  Global_in_count = Thread_count * Method_calls_per_thread

  # global stores
  Global_in = 1.upto(Global_in_count).to_a 
  Global_out = []

  # base method
  def base_method
    Global_out.push Global_in.pop
  end

  # threads
  def n_threads(n, &blk)
    n.times.map { Thread.new &blk }
  end

  # consistency check
  def consistency_check
    "uniq length: #{Global_out.uniq.length}, total length: #{Global_out.length}"
  end

end

# init
if __FILE__ == $0
  include AtomicityTestWithConcurrentThreadsAndGlobalVariables
  n_threads(Thread_count) do
    Method_calls_per_thread.times { base_method }
  end.each &:join
  puts consistency_check
end

如果我以错误的方式思考这件事,请告诉我。可以预期多个线程以原子方式共享全局状态,因此尝试查找竞争条件毫无意义吗?

另外一些奇怪的是,ruby 1.8.7比ruby 2.3.0更快。

> rbenv global 1.8.7-p370

> time ruby test.rb
uniq length: 100000, total length: 100000
0.18user 0.01system 0:00.24elapsed 81%CPU (0avgtext+0avgdata 21100maxresident)k
0inputs+0outputs (0major+10495minor)pagefaults 0swaps
13:00:34, taken:36, load:1.53, /home/max/Documents

> rbenv global 2.3.0

> time ruby test.rb
uniq length: 100000, total length: 100000
1.72user 0.38system 0:02.28elapsed 92%CPU (0avgtext+0avgdata 74680maxresident)k
0inputs+0outputs (0major+54022minor)pagefaults 0swaps
13:00:41, load:1.64, /home/max/Documents

它采用0.01秒系统,1.8.7和0.38,2.3.0

0 个答案:

没有答案