如何将值返回给函数然后在同一函数中启动一个线程?

时间:2017-02-09 16:36:01

标签: ruby multithreading

有没有办法为函数返回一个值,然后在该函数中调用一个线程?例如:

def foo
  return fast_function
  Thread.new do
    slow_function
  end
end

这背后的原因是fast_functionslow_function都写入同一资源。但我想确保fast_function首先运行并完成,并在foo写入共享资源之前将其值返回slow_function。在某些情况下,slow_functionfast_function之前完成,并且我遇到了竞争条件。

编辑: 关于这个问题的更多背景。这与我试图实现的服务器端事件有关。我想让fast_function计算一个事件ID并返回和html。虽然slow_function负责通过事件ID通知客户端该过程已完成。但是,在某些情况下,slow_function会在客户端事件知道要侦听的位置之前通知客户端,因为fast_function尚未返回事件ID。

1 个答案:

答案 0 :(得分:0)

不,返回将退出该函数,它也将退出yield块中的函数。在我看来,这个问题有多种解决方案。

实际上它非常适合并发Ruby的承诺(https://github.com/ruby-concurrency/concurrent-ruby

你可以做到这样的事情:

def foo

   fast = Concurrent::Promise.execute{ fast_function }
   slow = promises[:fast].then{ slow_function }
                         .on_fullfill{ notify_client }
   return fast.value
end

您可以猜测它会返回快速函数的值。 但是如果慢功能完成,它也会调用on_fullfill函数(或者一个proc)。最重要的是,它将保证秩序。

注意:我不确定我是否理解你,如果你想同时启动展位线程,但要确保快速首先完成。你可以这样做:

fast = Concurrent::Promise.execute{ fast_function }
slow = Concurrent::Promise.execute{ slow_function }

render fast.value # Or what you ever do with the html. 
                  #.value will wait for the Promise to finish.
result slow = slow.value

通过这种方式你可以并行启动booth功能,但请确保你会先得到快速的答案。

编辑1:我想知道这一点,我不确定你是否想要一个异步任务。因为你发布了一个最小的例子(coruse的正确性),这很难分辨。 如果你只想拥有一个以正确的顺序返回botth函数返回的函数,你可以只做一个收益:

def foo
  yield fast_function
  yield slow_function
end