ruby-on-rails - 在 ruby​​ 中通过并行处理有序插入数据

标签 ruby-on-rails ruby multithreading parallel-processing

这是我的 Ruby 代码

getLikes() 方法使用 token t

hash 格式获取用户的 Facebook 点赞
def multi
    token = ["Facebook token 1","Facebook token 2","Facebook token 3",...]
    @data = []
    @threads = []

    token.each do |t|
        @threads << Thread.new{@data << getLikes(t)}
    end

    @threads.each do |th|
        th.join
    end


    render json: @data
end

问题是 @data 的内容的数据因为并行化而不在同一顺序。

为了解决这个问题,我将第一个循环修改为

i = 0
token.each do |t|
    @threads << Thread.new{@data[i] = getLikes(t)}
    i = i + 1
end

但是程序不会等待所有线程完成。我在 @data 数组中得到了一些 null 值。

解决这个问题的好方法是什么?

谢谢

最佳答案

问题是您的代码不是线程安全的,因为它在线程之间使用共享变量而不使用互斥锁。哈希在 Ruby 中不是线程安全的。

解决方案是在您的线程中返回简单的值,并在您的主代码中聚合结果。要保持顺序,只需返回 token 和值:

def multi
  token = ["Facebook token 1","Facebook token 2","Facebook token 3",...]
  @threads = []

  token.each do |t|
    @threads << Thread.new{[t, getLikes(t)]}
  end

  data = Hash[@threads.map(&:value)] # this will block the main thread

  sorted_data = []
  token.each do |t|
    sorted_data << data[t]
  end

  render json: sorted_data
end

关于ruby-on-rails - 在 ruby​​ 中通过并行处理有序插入数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23853864/

相关文章:

ruby-on-rails - 如何在 Ruby 中给定 URL 中的 base64 编码媒体

mysql - 使用 structure.sql 而不是 schema.rb 为 MySQL 配置公寓 gem 以创建新租户

c++ - 是否有可能获得主线程的线程对象,以及 `join()`?

python - 我应该使用线程或多处理来对 Python 进行暴力破解吗?

ruby-on-rails - 什么是 "common"在日志中仅显示一次消息的实践/技术?

ruby-on-rails - Rails 3. 使用 Formtastic 有条件地显示字段

ruby - 为什么二进制文件在压缩时会损坏?

multithreading - 彼得森的解决方案如何解决有界等待?

ruby-on-rails - 无法连接到服务器 : "/var/run/postgresql/.s.PGSQL.5432"?

ruby-on-rails - 为什么 Rails 将 "drive"更改为 "drife"?