简体   繁体   English

Ruby中的线程会提高并发性吗?

[英]Do threads in Ruby improve concurrency?

My question is specific to MRI. 我的问题特定于MRI。 It looks like since Ruby 1.9 all threads are native but MRI continues to run them one at a time. 从Ruby 1.9开始,所有线程看起来都是本地的,但是MRI继续一次运行一个线程。 This sounds like parallel execution of threads is not possible in MRI but does using Threads improve concurrency in your program for something that looks like this? 这听起来像在MRI中无法并行执行线程,但是使用线程可以改善程序中的并发性吗?

In other words do you get any benefit from using threads to upload a lot of files onto S3? 换句话说,使用线程将大量文件上载到S3会获得任何好处吗?

# https://gist.github.com/milesmatthias/25c15fd8384d4a7e76f2

...    

file_number = 0
mutex       = Mutex.new
threads     = []

thread_count.times do |i|
  threads[i] = Thread.new {
    until files.empty?
      mutex.synchronize do
        file_number += 1
        Thread.current["file_number"] = file_number
      end
      file = files.pop rescue nil
      next unless file

      data = File.open(file)

      if File.directory?(data)
        data.close
        next
      else
        obj = s3_bucket.objects[path]
        obj.write(data, { acl: :public_read })
        data.close
      end

    end
  }
end
threads.each { |t| t.join }

...

Threads in Ruby improve concurrency, but do not increase parallelism. Ruby中的线程可以提高并发性,但不会增加并行性。 What that means is that threads allow Ruby to deal with multiple things at the same time (concurrency), but Ruby still cannot do multiple things at the same time (parallelism). 这意味着线程允许Ruby同时处理多个事务(并发),但是Ruby仍然不能同时处理多个事务(并行性)。

Why is this difference important? 为什么这种差异很重要? If your code needs a lot of CPU time, it will not improve from threads, because all threads have to use the same CPU. 如果您的代码需要大量CPU时间,则线程无法改善代码,因为所有线程必须使用同一CPU。 But if your code does a lot of IO (what usually means that the CPU is idling a lot), than your overall performance might improve a lot. 但是,如果您的代码执行大量IO(通常意味着CPU处于闲置状态),则总体性能可能会提高很多。

In your example (uploading files to S3) I would expect an increase in performance depending on your network bandwidth. 在您的示例中(将文件上传到S3),我希望性能会有所提高,具体取决于您的网络带宽。

YARV has a Giant VM Lock (GVL) that prevents two threads from entering the interpreter loop at the same time. YARV具有巨型VM锁(GVL),可以防止两个线程同时进入解释器循环。 That is true. 那是真实的。

However, this only means that you cannot have two parallel threads running Ruby code (or more precisely, YARV bytecode) at the same time. 但是,这仅意味着您不能有两个并行线程同时运行Ruby代码(或更准确地说是YARV字节码)。 You can have parallel threads running C code at the same time (and the entire core library, as well as big parts of the standard library, and some Gems are actually written in C, not Ruby), you can have parallel threads doing or waiting for I/O, you can have C extensions do what they like in parallel threads (except running Ruby code). 可以让并行线程同时运行C代码(以及整个核心库以及标准库的大部分内容,并且某些Gems实际上是用C而不是Ruby编写的),您可以让并行线程来做或等待对于I / O,您可以让C扩展在并行线程中完成其所需的工作(运行Ruby代码除外)。

So, yes, threads can improve performance even on YARV. 因此,是的,即使在YARV上,线程也可以提高性能。

Ruby MRI (aka YARV) threads can improve some kinds of operations, especially I/O. Ruby MRI(又名YARV)线程可以改善某些类型的操作,尤其是I / O。

The VM runs one thread at a time, even on multi-core processors, because of a global lock. 由于全局锁定,VM一次运行一个线程,即使在多核处理器上也是如此。

The VM has special optimizations for some operations including I/O. VM对某些操作(包括I / O)进行了特殊的优化。 When a thread is waiting for an I/O operation, then Ruby transfers control to the next thread. 当线程正在等待I / O操作时,Ruby将控制权转移到下一个线程。 It is also possible for threads to call non-Ruby code such as native C extensions, and these may be able to run in parallel. 线程也可以调用非Ruby代码,例如本机C扩展,并且这些线程可以并行运行。

When I built an I/O uploader app on AWS, our benchmarks showed that in practice we could get total throughput benefits up to about 100 threads. 当我在AWS上构建I / O上载器应用程序时,我们的基准测试表明,实际上,我们可以获得多达100个线程的总吞吐量收益。 We had a very fast network connection, and we found that the major benefit of the threading was coming because of the comparatively long time to open a new connection. 我们的网络连接速度非常快,我们发现线程化的主要好处是由于打开新连接的时间相对较长。

Your mileage may vary, so benchmark. 您的里程可能会有所不同,因此请进行基准测试。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM