Ruby 线程使用不同的参数调用相同的函数

标签 ruby multithreading

我正在使用多个线程(例如 10 个线程)调用同一个 Ruby 函数。每个线程将不同的参数传递给函数。

例子:

def test thread_no  
    puts "In thread no." + thread_no.to_s
end

num_threads = 6
threads=[]

for thread_no in 1..num_threads
    puts "Creating thread no. "+thread_no.to_s
    threads << Thread.new{test(thread_no)}
end

threads.each { |thr| thr.join }

输出: 创建线程号1个 创建线程号2个 创建线程号3个 创建线程号4个 在线程 4
创建线程号5个 创建线程号6个 在第 6 号线程中
在第 6 号线程中
在第 6 号线程中
在第 6 号线程中
在线程 6 中

当然我想得到输出:在线程号。 1 (2,3,4,5,6) 我能以某种方式实现它吗?

最佳答案

问题是 for 循环。在 Ruby 中,它重用了单个变量。 所以线程体的所有 block 都访问同一个变量。 this 变量在循环结束时为 6。线程本身可能仅在循环结束后启动。

您可以使用each 循环来解决这个问题。它们的实现更加清晰,每个循环变量都独立存在。

(1..num_threads).each do | thread_no |
    puts "Creating thread no. "+thread_no.to_s
    threads << Thread.new{test(thread_no)}
end

不幸的是,ruby 中的for 循环是一个令人惊讶的来源。所以最好始终使用 each 循环。

添加: 您还可以为 Thread.new 提供一个或多个参数,这些参数将传递到线程主体 block 中。通过这种方式,您可以确保该 block 在其自身范围之外不使用任何变量,因此它也适用于 for 循环。

threads <<  Thread.new(thread_no){|n| test(n) }

关于Ruby 线程使用不同的参数调用相同的函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33625574/

相关文章:

css - 如何使用 Sinatra 在当前页面上突出显示导航菜单?

ruby - Sinatra 的测试框架

ruby - 使用 Ruby 在多个操作系统中读取文件名而没有编码问题

java - ReentrantReadWriteLock 与同步

java - 提前更新场景,同时仍然渲染前一帧

c# - 尝试在 sleep 循环中获取锁是否可以(避免死锁、饥饿等...)?

ios - 与核心音频线程同步

ruby-on-rails - rails render_to_string 在部分 View 中给出错误

c# - 交换对象和线程安全性有任何问题吗?

ruby-on-rails - date_field_tag,如何设置默认日期? [ rails 上的 ruby ]