2011-06-14 76 views
0

我在通过sftp上传文件的程序中使用线程。可以上传的文件数量可能非常大或很小。我希望能够同时上传5个或更少,并且如果还有更多人在等待。我的理解通常是一个条件变量将用于此,但它看起来像我一次只允许1线程。限制并发线程

cv = ConditionVariable.new 

t2 = Thread.new { 
    mutex.synchronize { 
    cv.wait(mutex) 
    upload(file) 
    cv.signal 
    } 
} 

我认为应该告诉它等待cv在完成时等待释放它。我的问题是,我怎么能这样做,允许一次超过1个,但仍然限制数量?

编辑:我使用Ruby 1.8.7在Windows上从1次点击安装

+0

您正在使用的Ruby版本对于此问题很重要。 – 2011-06-14 15:17:37

回答

1

谨慎的说法 - 除非您使用JRuby,否则在Ruby中没有真正的并发性。此外,线程中的异常将冻结主循环,除非您处于调试模式。

require "thread" 

POOL_SIZE = 5 

items_to_process = (0..100).to_a 

message_queue = Queue.new 

start_thread = 
    lambda do 
    Thread.new(items_to_process.shift) do |i| 
     puts "Processing #{i}" 
     message_queue.push(:done) 
    end 
    end 

items_left = items_to_process.length 

[items_left, POOL_SIZE].min.times do 
    start_thread[] 
end 

while items_left > 0 
    message_queue.pop 
    items_left -= 1 
    start_thread[] unless items_left < POOL_SIZE 
end 
+1

这是不正确的。 MRI版本1.9.2使用带有GIL的本地/内核线程。它不如JRuby或MacRuby线程有效,但它们不是1.8.7的绿色线程。在做IO工作的情况下(如问题所暗示的)1.9.2线程非常有用(如果你不相信我,请看Typhoeus)。 – coreyward 2011-06-14 18:11:03

+0

@coreyward同意。我一直认为,即使在1.8.7 IO实际上也是并行的。很难相信Ruby使用冻结调度程序的IO系统阻塞调用。此外,线程池可用于限制套接字使用,文件句柄等。 – 2011-06-14 18:50:16