首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >理解细胞并发性

理解细胞并发性
EN

Stack Overflow用户
提问于 2016-01-28 12:42:20
回答 1查看 533关注 0票数 10

下面是我的细胞密码。

  1. client1.rb是两个客户之一。(我把它命名为客户1)
  2. client2.rb是2位客户中的第二位。(命名为客户2)

注意:

上述两个客户机之间唯一的区别是传递给服务器的文本。即('client-1''client-2' )

在测试这两个客户端时(通过并行运行),对以下两个服务器进行测试(一次)。我发现了非常奇怪的结果

  1. server1.rb (一个基本的例子,从README.md的赛珍珠-zmq) 使用它作为上述两个客户端的示例服务器,将导致任务的并行执行

输出

代码语言:javascript
复制
ruby server1.rb

Received at 04:59:39 PM and message is client-1
Going to sleep now
Received at 04:59:52 PM and message is client-2

注意:

当client1.rb请求处于睡眠状态时,会处理client2.rb消息。

  1. server2.rb 使用它作为上面两个客户端的示例服务器,不会导致任务的并行执行

输出

代码语言:javascript
复制
ruby server2.rb

Received at 04:55:52 PM and message is client-1
Going to sleep now
Received at 04:56:52 PM and message is client-2

注意:

客户端-2被要求等待60秒,因为客户端-1正在睡觉(60秒睡眠)

我多次运行上述测试,结果都是相同的行为。

有谁能从上面的测试结果中解释一下。

问题:为什么要等待60秒才能处理另一个请求,如server2.rb中所注意到的那样。

Ruby版本

ruby -v

ruby 2.1.2p95 (2014-05-08 revision 45877) [x86_64-darwin13.0]

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-01-30 17:52:18

使用你们的专家,我证实了这个问题可以在MRI 2.2.1以及jRuby 1.7.21Rubinius 2.5.8中复制.server1.rbserver2.rb的区别在于在后者中使用了DisplayMessagemessage类方法。

sleepDisplayMessage中的使用超出了Celluloid的范围。

sleepserver1.rb中使用时,它实际上使用的是Celluloid.sleep,而在server2.rb中使用的是Kernel.sleep。将邮箱锁定为Server,直到60秒过去。这将防止将来的方法调用要处理的该参与者,直到邮箱再次处理消息(方法调用该参与者)。

解决这一问题有三种方法:

  • 使用defer {}future {}块。
  • 显式调用Celluloid.sleep而不是sleep (如果没有以Celluloid.sleep身份显式调用,则使用sleep将最终调用Kernel.sleep,因为DisplayMessage不像Server那样include Celluloid )
  • DisplayMessage.message的内容像server1.rb那样带到handle_message中;或者至少在Server中,这是Celluloid作用域中的内容,并且将使用正确的sleep

defer {}方法:

代码语言:javascript
复制
def handle_message(message)
  defer {
    DisplayMessage.message(message)
  }
end

Celluloid.sleep方法:

代码语言:javascript
复制
class DisplayMessage
    def self.message(message)
      #de ...
      Celluloid.sleep 60
    end
end

这并不是真正的范围问题,而是异步问题。

重申一下,更深层次的问题不是sleep的范围.这就是为什么deferfuture是我最好的推荐。但我要在这里发表我的评论:

使用deferfuture会将一个任务推送到另一个线程中,这会导致参与者被捆绑在另一个线程中。如果使用future,任务完成后可以获得返回值,如果使用defer,则可以触发&忘记。

但是更好的是,创造另一个演员来完成那些容易被束缚的任务,甚至把其他的演员集中在一起……如果deferfuture不适合你。

我非常乐意回答这个问题引起的后续问题;我们有一个非常活动邮件列表和IRC频道。你慷慨的赏赐是值得称赞的,但我们中的许多人都会帮助你。

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35061826

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档