代码之家  ›  专栏  ›  技术社区  ›  Jesse Jashinsky

Ruby进程之间的共享变量

  •  11
  • Jesse Jashinsky  · 技术社区  · 14 年前

    我有一个Ruby程序,它可以加载两个非常大的yaml文件,所以我可以通过分叉一些进程来利用多个内核来加快速度。我试过寻找,但是我很难弄清楚如何或者即使我可以在不同的过程中共享变量。

    以下代码是我目前拥有的代码:

    @proteins = ""
    @decoyProteins = "" 
    
    fork do
      @proteins = YAML.load_file(database)
      exit
    end
    
    fork do
      @decoyProteins = YAML.load_file(database)
      exit
    end
    
    p @proteins["LVDK"]
    

    P 但由于分叉,显示为零。

    那么,是否可以让分叉的流程共享变量呢?如果是这样,怎么办?

    4 回复  |  直到 10 年前
        1
  •  13
  •   rampion    14 年前

    一个问题是你需要使用 Process.wait 等待分叉的进程完成。另一个是不能通过变量进行进程间通信。看到这一点:

    @one = nil
    @two = nil
    @hash = {}
    pidA = fork do
        sleep 1
        @one = 1
        @hash[:one] = 1
        p [:one, @one, :hash, @hash] #=> [ :one, 1, :hash, { :one => 1 } ]
    end
    pidB = fork do
        sleep 2
        @two = 2
        @hash[:two] = 2
        p [:two, @two, :hash, @hash] #=> [ :two, 2, :hash, { :two => 2 } ]
    end
    Process.wait(pidB)
    Process.wait(pidA)
    p [:one, @one, :two, @two, :hash, @hash] #=> [ :one, nil, :two, nil, :hash, {} ]
    

    进行进程间通信的一种方法是使用管道( IO::pipe )在叉子之前打开它,然后让叉子的每一侧都封闭管子的一端。

    ri IO::pipe :

        rd, wr = IO.pipe
    
        if fork
          wr.close
          puts "Parent got: <#{rd.read}>"
          rd.close
          Process.wait
        else
          rd.close
          puts "Sending message to parent"
          wr.write "Hi Dad"
          wr.close
        end
    
     _produces:_
    
        Sending message to parent
        Parent got: <Hi Dad>
    

    如果要共享变量,请使用线程:

    @one = nil
    @two = nil
    @hash = {}
    threadA = Thread.fork do
        sleep 1
        @one = 1
        @hash[:one] = 1
        p [:one, @one, :hash, @hash] #=> [ :one, 1, :hash, { :one => 1 } ] # (usually)
    end
    threadB = Thread.fork do
        sleep 2
        @two = 2
        @hash[:two] = 2
        p [:two, @two, :hash, @hash] #=> [ :two, 2, :hash, { :one => 1, :two => 2 } ] # (usually)
    end
    threadA.join
    threadB.join
    p [:one, @one, :two, @two, :hash, @hash] #=> [ :one, 1, :two, 2, :hash, { :one => 1, :two => 2 } ]
    

    但是,我不确定线程是否会在IO绑定时获得任何收益。

        2
  •  1
  •   maasha    10 年前

    Cod 用于进程间通信,允许您在分叉进程之间轻松发送数据。

        3
  •  0
  •   regularfry    14 年前

    在进程之间共享变量是可能的;Druby可能是实现这一点的入口方法的最低障碍。

        4
  •  0
  •   Trey    14 年前

    如果要共享数据,您可能希望使用线程而不是fork。

    http://ruby-doc.org/docs/ProgrammingRuby/html/tut_threads.html

    哦,如果你真的想利用线程,你就需要使用JRuby。在[C]Ruby1.9中,您可能总是想看看纤维。不过我还没看过,我不知道这是否是你的解决方案。