Tag: 纤维

Ruby的光纤4kB堆栈大小的后果

纤维对我来说是一个相对较新的概念。 我知道每个光纤的堆栈大小限制为4kB,我继续读到我应该“小心”这个。 这个限制对现实世界的影响究竟是什么? 编辑: 似乎这个4kB限制毕竟不是这样的障碍,它需要光纤本身内的大量局部变量(4,045)才能引发SystemStackError。 count = 0 loop do count += 1 puts count varlist = String.new count.times do |i| varlist += “a#{i} = 1\n” end s = “fiber = Fiber.new do \n #{varlist} \n end \n fiber.resume” eval(s) end 不是最优雅的代码,但它似乎certificate了光纤堆栈的局限性。 好像它只是返回值,局部变量(所有这些变量都包含对堆上对象的引用)和方法调用放在堆栈上。 我还没有测试从光纤调用的方法中的局部变量等是否是光纤堆栈的一部分。 编辑2: 修改了上面的代码。 看来,被调用方法中的变量等成为光纤堆栈的一部分。 如果是这种情况,那么调用深度(即使没有递归)也可能是一个问题,因为方法本身可能需要更多的空间而不是变量(它们似乎是对堆上对象的透明引用)。 以下代码在第4,031次迭代时失败,并指示被调用方法中的变量成为光纤堆栈的一部分: count = 0 loop do count […]

如何使用Ruby(和open-uri)并行处理数组中的项

我想知道如何使用open-uri打开多个并发连接? 我认为我需要使用线程或纤维,但我不确定。 示例代码: def get_doc(url) begin Nokogiri::HTML(open(url).read) rescue Exception => ex puts “Failed at #{Time.now}” puts “Error: #{ex}” end end array_of_urls_to_process = [……] # How can I iterate over items in the array in parallel (instead of one at a time?) array_of_urls_to_process.each do |url| x = get_doc(url) do_something(x) end

枚举器如何在Ruby 1.9.1中工作?

这个问题不是关于如何在Ruby 1.9.1中使用枚举器,而是我很好奇它们是如何工作的。 这是一些代码: class Bunk def initialize @h = [*1..100] end def each if !block_given? enum_for(:each) else 0.upto(@h.length) { |i| yield @h[i] } end end end 在上面的代码中,我可以使用e = Bunk.new.each ,然后使用e.next , e.next来获取每个连续的元素,但是它究竟是如何暂停执行然后在正确的位置恢复? 我知道如果0.upto的产量被0.upto取代,那么它很容易理解,但这不是这里的情况。 这是一个普通的老yield ,它是如何工作的? 我看了一下enumerator.c,但对我来说这是不可理解的。 也许有人可以在Ruby中提供一个实现,使用光纤,而不是1.8.6样式的基于延续的枚举器,这一切都清楚了吗?

Ruby Fibers可以并发吗?

我试图在我的程序中加快速度,并且我被告知Ruby Fibers比线程更快,并且可以利用多个核心。 我环顾四周,但我找不到如何实际同时运行不同的纤维。 使用线程,您可以执行此操作: threads = [] threads << Thread.new {Do something} threads << Thread.new {Do something} threads.each {|thread| thread.join} 我看不出怎么用纤维做这样的事情。 我所能找到的只是yield和resume ,这似乎只是一堆起始和停止在纤维之间。 有没有办法与光纤进行真正的并发?