当 MRI 1.9 启动时,它会产生两个本地线程。一个线程用于 VM,另一个用于处理信号。Rubinis 使用这种策略,JVM 也是如此。管道可用于传递来自其他进程的任何信息。
至于FileUtils
模块,cd
, pwd
, mkdir
, rm
, ln
, cp
, mv
, chmod
,chown
和touch
方法在某种程度上都是使用StreamUtils
子模块的内部 API 外包给 OS 本地实用程序的,而第二个线程则等待来自 an 的信号。外部过程。由于这些方法是相当线程安全的,因此无需锁定解释器,因此这些方法不会相互阻塞。
编辑:
MRI 1.8.7 相当聪明,它知道当 Thread 正在等待一些外部事件(例如浏览器发送 HTTP 请求)时,可以将 Thread 置于睡眠状态,并在检测到数据时将其唤醒。- Evan Phoenix 来自 Engine Yard 的Ruby、并发和你
FileUtils 的实现基本实现从查看源代码来看,1.8.7 并没有太大的改变。1.8.7 还使用休眠定时器线程来等待 IO 响应。1.9 的主要区别在于使用原生线程而不是绿色线程。线程源代码也更加精致。
线程安全的意思是,由于进程之间没有共享任何内容,因此没有理由锁定全局解释器。有一种误解认为 Ruby 在执行某些任务时会“阻塞”。每当一个线程必须阻塞时,即在不使用任何 cpu 的情况下等待,Ruby 会简单地调度另一个线程。然而,在某些情况下,例如机架服务器使用 20% 的 CPU 等待响应,解锁解释器并允许并发线程在等待期间处理其他请求可能是合适的。从某种意义上说,这些线程是并行工作的。GIL 通过rb_thread_blocking_region
API 解锁。这是一个关于这个主题的好帖子。