【问题标题】:Green thread in Ruby 1.9?Ruby 1.9 中的绿线?
【发布时间】:2012-10-17 05:34:38
【问题描述】:

与 Ruby 1.8 (MRI) 不同,Ruby 1.9 使用本机线程。

但是能否请 Ruby 1.9.3 创建一个绿色线程而不是原生线程?

--

我为什么要这样?

用于测试目的。

我正在尝试创建一个简单的 TCP 服务器,它可以接受数千个并发连接,这些连接会在返回一些结果之前休眠几秒钟。

在 Ruby 1.8 中,我可以轻松创建数千个线程,因此并发连接数的唯一限制是操作系统。

在 Ruby 1.9 中这似乎是不可能的。

这段代码说明了我的意思:

require 'thread'

m = Mutex.new
c = 0
ta = Array.new 10000

ta.fill do
  Thread.new do
    m.synchronize { c += 1; p "created #{c}th" if c%100 == 0; }
    sleep 15
    m.synchronize { c -= 1; p "destroyed #{c+1}th" if c%100 == 0; }
  end
end

ta.each {|t| t.join}

它在 Ruby 1.8 中运行良好,但在 1.9 中就很惨了。

--

不幸的是,在对 eventmachine 及其 add_timer 进行了一些试验之后,我能想到的最好的就是 Node.js 服务器:

var http = require('http');
http.createServer(function (req, res) {
  res.writeHead(200, {'Content-Type': 'text/plain'});
  setTimeout(function() {res.end('Hello World\n');}, 10000 );
}).listen(8081, '127.0.0.1');
console.log('Server running at http://127.0.0.1:8081/');

如果有人可以用 EventMachine 证明同样的事情,我很乐意接受这个答案。

【问题讨论】:

  • 光纤不存在问题吗?
  • @pje 更新了问题,您不能用该代码中的纤维替换线程吗?
  • 请注意setTimeoutsleep 完全不同。 setTimeout 安排一个函数在未来某个时间运行。这是一种异步、非阻塞的方法,而sleep 将 CPU 阻塞当前线程一段指定的时间。
  • @tabdulla 是的,这就是我提到 EventMachine 的原因 - 它的 add_timer 应该与 addTimeout 相同,但我未能使其工作

标签: ruby multithreading


【解决方案1】:

简而言之,答案是否定的。 1.9 中的线程模型现在使用本机线程,而绿色线程本身已被弃用。

确切了解为什么要使用绿色线程而不是操作系统管理的线程来建议适当的替代方案会很有帮助。例如,根据您的用例,您可以考虑使用具有某种自己滚动调度的 Proc 对象或 Fibers 作为本机线程的轻量级替代方案。如果您发现线程的创建时间是一个限制因素,您还可以查看线程/光纤池。

【讨论】:

  • 感谢答案 - 更新了我的问题。我不认为在我的情况下使用 Fibers 是一种选择,或者是吗?
  • 我们应该在哪里看到这些变化?更新日志?
猜你喜欢
  • 2012-07-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-19
  • 2011-06-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多