使用Ruby线程和put

时间:2017-04-14 15:50:35

标签: ruby multithreading

我正在编写一个程序,它将执行许多检查并通过puts输出结果。我想使用线程来加速这个过程。但是,输出包括不一致的新行。

如何清除此输出?

实施例

> (1..99).each_with_object([]) {|i, threads| threads << Thread.new {sleep(rand 2) && puts(i)} }.each(&:join)
7
202535
36605562
7882
8959958
2826

29
433941
445258

69728063
777975



85496

22

14
24



3850



9712
9892


47

40

71
84

94
49







1
2
152187131627234218194531535759
305417
34647448
735111
66684676
838137
6133
679093
917099
3






56

32


10

6















88



86

65

2 个答案:

答案 0 :(得分:1)

更新了Tin Man的评论

使用print / printfputs并明确提供换行符\n(因为puts可能会单独写下新行#{1}}休息和其他线程可能跳进来。)

(1..99).each_with_object([]) {|i, threads| threads << Thread.new {sleep(rand 2) && print("#{i}\n") } }.each(&:join)

答案 1 :(得分:0)

您的线程都在共享资源:stdout。每当你有共享资源的线程时,你需要确保一次没有多个访问该资源,否则你会发现干扰。

以下是解决此问题的两种方法。首先,您可以更改线程以仅返回值,然后执行所有打印:

threads = (1..99).map {|i| Thread.new { sleep(rand 2) && i } }
threads.each do |t|
  t.join
  puts t.value
end

如果你的线程都以大约相同的速度运行,这是一个很好的方法,因为它会挂在最慢的线程上(即使其他更快的线程已经完成)。

或者,使用互斥锁来保护标准输出。

mutex = Thread::Mutex.new
(1..99).map do |i|
  Thread.new { sleep(rand 2); mutex.synchronize { puts i } }
end.each(&:join)

这将让每个线程独立运行和打印。但是如果你需要每个线程进行大量打印,那就不太好了:他们越多地使用互斥锁,你的线程就越慢。

相关问题