[前][次][番号順一覧][スレッド一覧]

ruby-changes:64557

From: Koichi <ko1@a...>
Date: Thu, 24 Dec 2020 17:52:19 +0900 (JST)
Subject: [ruby-changes:64557] 8664c3ddef (master): update doc/ractor.md

https://git.ruby-lang.org/ruby.git/commit/?id=8664c3ddef

From 8664c3ddef548b53c4f5c5264cccd24ae08f174f Mon Sep 17 00:00:00 2001
From: Koichi Sasada <ko1@a...>
Date: Thu, 24 Dec 2020 17:41:48 +0900
Subject: update doc/ractor.md


diff --git a/doc/ractor.md b/doc/ractor.md
index 23b28ae..0ca3632 100644
--- a/doc/ractor.md
+++ b/doc/ractor.md
@@ -8,14 +8,14 @@ Ractor is designed to provide a parallel execution feature of Ruby without threa https://github.com/ruby/ruby/blob/trunk/doc/ractor.md#L8
 
 You can make multiple Ractors and they run in parallel.
 
-* Ractors run in parallel.
+* `Ractor.new{ expr }` creates a new Ractor and `expr` is run in parallel on a parallel computer.
 * Interpreter invokes with the first Ractor (called *main Ractor*).
 * If main Ractor terminated, all Ractors receive terminate request like Threads (if main thread (first invoked Thread), Ruby interpreter sends all running threads to terminate execution).
 * Each Ractor has 1 or more Threads.
-  * Threads in a Ractor shares a Ractor-wide global lock like GIL (GVL in MRI terminology), so they can't run in parallel (without releasing GVL explicitly in C-level).
+  * Threads in a Ractor shares a Ractor-wide global lock like GIL (GVL in MRI terminology), so they can't run in parallel (without releasing GVL explicitly in C-level). Threads in different ractors run in parallel.
   * The overhead of creating a Ractor is similar to overhead of one Thread creation.
 
-### Limited sharing
+### Limited sharing between multiple ractors
 
 Ractors don't share everything, unlike threads.
 
@@ -24,7 +24,8 @@ Ractors don't share everything, unlike threads. https://github.com/ruby/ruby/blob/trunk/doc/ractor.md#L24
   * Immutable objects: frozen objects which don't refer to unshareable-objects.
     * `i = 123`: `i` is an immutable object.
     * `s = "str".freeze`: `s` is an immutable object.
-    * `a = [1, [2], 3].freeze`: `a` is not an immutable object because `a` refer unshareable-object `[2]` (which is not frozen).
+    * `a = [1, [2], 3].freeze`: `a` is not an immutable object because `a` refers unshareable-object `[2]` (which is not frozen).
+    * `h = {c: Object}.freeze`: `h` is an immutable object because `h` refers Symbol `:c` and shareable `Object` class object which is not frozen.
   * Class/Module objects
   * Special shareable objects
     * Ractor object itself.
@@ -35,27 +36,28 @@ Ractors don't share everything, unlike threads. https://github.com/ruby/ruby/blob/trunk/doc/ractor.md#L36
 Ractors communicate with each other and synchronize the execution by message exchanging between Ractors. There are two message exchange protocols: push type (message passing) and pull type.
 
 * Push type message passing: `Ractor#send(obj)` and `Ractor.receive()` pair.
-  * Sender ractor passes the `obj` to receiver Ractor.
-  * Sender knows a destination Ractor (the receiver of `r.send(obj)`) and the receiver does not know the sender (accept all message from any ractors).
-  * Receiver has infinite queue and sender enqueues the message. Sender doesn't block to put message.
-  * This type is based on actor model
+  * Sender ractor passes the `obj` to the ractor `r` by `r.send(obj)` and receiver ractor receives the message with `Ractor.receive`.
+  * Sender knows the destination Ractor `r` and the receiver does not know the sender (accept all message from any ractors).
+  * Receiver has infinite queue and sender enqueues the message. Sender doesn't block to put message into this queue.
+  * This type message exchangin is employed by many other Actor-based language.
+  * `Ractor.receive_if{ filter_expr }` is a variant of `Ractor.receive` to select a message.
 * Pull type communication: `Ractor.yield(obj)` and `Ractor#take()` pair.
-  * Sender ractor declare to yield the `obj` and receiver Ractor take it.
-  * Sender doesn't know a destination Ractor and receiver knows the sender (the receiver of `r.take`).
+  * Sender ractor declare to yield the `obj` by `Ractor.yield(obj)` and receiver Ractor take it with `r.take`.
+  * Sender doesn't know a destination Ractor and receiver knows the sender Ractor `r`.
   * Sender or receiver will block if there is no other side.
 
 ### Copy & Move semantics to send messages
 
 To send unshareable objects as messages, objects are copied or moved.
 
-* Copy: use deep-copy (like dRuby)
-* Move: move membership
+* Copy: use deep-copy.
+* Move: move membership.
   * Sender can not access the moved object after moving the object.
   * Guarantee that at least only 1 Ractor can access the object.
 
 ### Thread-safety
 
-Ractor helps to write a thread-safe program, but we can make thread-unsafe programs with Ractors.
+Ractor helps to write a thread-safe concurrent program, but we can make thread-unsafe programs with Ractors.
 
 * GOOD: Sharing limitation
   * Most objects are unshareable, so we can't make data-racy and race-conditional programs.
@@ -68,18 +70,18 @@ Ractor helps to write a thread-safe program, but we can make thread-unsafe progr https://github.com/ruby/ruby/blob/trunk/doc/ractor.md#L70
   * Some kind of shareable objects can introduce transactions (STM, for example). However, misusing transactions will generate inconsistent state.
 
 Without Ractor, we need to trace all of state-mutations to debug thread-safety issues.
-With Ractor, you can concentrate to suspicious
+With Ractor, you can concentrate to suspicious code which are shared with Ractors.
 
 ## Creation and termination
 
 ### `Ractor.new`
 
-* `Ractor.new do expr end` generates another Ractor.
+* `Ractor.new{ expr }` generates another Ractor.
 
 ```ruby
 # Ractor.new with a block creates new Ractor
 r = Ractor.new do
-  # This block will be run in parallel
+  # This block will be run in parallel with other ractors
 end
 
 # You can name a Ractor with `name:` argument.
@@ -93,15 +95,11 @@ r.name #=> 'test-name' https://github.com/ruby/ruby/blob/trunk/doc/ractor.md#L95
 ### Given block isolation
 
 The Ractor execute given `expr` in a given block.
-Given block will be isolated from outer scope by `Proc#isolate`.
+Given block will be isolated from outer scope by `Proc#isolate`. To prevent sharing unshareable objects between ractors, block outer-variables, `self` and other information are isolated.
 
-```ruby
-# To prevent sharing unshareable objects between ractors,
-# block outer-variables, `self` and other information are isolated.
-# Given block will be isolated by `Proc#isolate` method.
-# `Proc#isolate` is called at Ractor creation timing (`Ractor.new` is called)
-# and it can cause an error if block accesses outer variables.
+Given block will be isolated by `Proc#isolate` method (not exposed yet for Ruby users). `Proc#isolate` is called at Ractor creation timing (`Ractor.new` is called). If given Proc object is not enable to isolate because of outer variables and so on, an error will be raised.
 
+```ruby
 begin
   a = true
   r = Ractor.new do
@@ -116,6 +114,7 @@ end https://github.com/ruby/ruby/blob/trunk/doc/ractor.md#L114
 
 ```ruby
 r = Ractor.new do
+  p self.class #=> Ractor
   self.object_id
 end
 r.take == self.object_id #=> false
@@ -177,18 +176,23 @@ end https://github.com/ruby/ruby/blob/trunk/doc/ractor.md#L176
 
 ## Communication between Ractors
 
-Communication between Ractors is achieved by sending and receiving messages.
+Communication between Ractors is achieved by sending and receiving messages. There is two way to communicate each other.
 
 * (1) Message sending/receiving
   * (1-1) push type send/receive (sender knows receiver). similar to the Actor model.
   * (1-2) pull type yield/take (receiver knows sender).
-* (2) Using shareable container objects (not implemented yet)
+* (2) Using shareable container objects
+  * Ractor::TVar gem ([ko1/ractor-tvar](https://github.com/ko1/ractor-tvar))
+  * more?
 
-Users can control blocking on (1), but should not control on (2) (only manage as critical section).
+Users can control program execution timing with (1), but should not control with (2) (only manage as critical section).
+
+For message sending and receiving, there are two types APIs: push type and pull type.
 
 * (1-1) send/receive (push type)
   * `Ractor#send(obj)` (`Ractor#<<(obj)` is an aliases) send a message to the Ractor's incoming port. Incoming port is connected to the infinite size incoming queue so `Ractor#send` will never block.
   * `Ractor.receive` dequeue a message from its own incoming queue. If the incoming queue is empty, `Ractor.receive` calling will block.
+  * `Ractor.receive_if{|msg| filter_expr }` is variant of `Ractor.receive`. `receive_if` only receives a message which `filter_expr` is true (So `Ractor.receive` is same as `Ractor.receive_if{ true }`.
 * (1-2) yield/take (pull type)
   * `Ractor.yield(obj)` send an message to a Ractor which are calling `Ractor#take` via outgoing port . If no Ractors are waiting for it, the `Ractor.yield(obj)` will block. If multiple Ractors are waiting for `Ractor.yield(obj)`, only one Ractor can receive the message.
   * `Ractor#take` receives a message which is waiting by `Ractor.yield(obj)` method from the specified Ractor. If the Ractor does not call `Ractor.yield` yet, the `Ractor#take` call will block.
@@ -196,13 +200,13 @@ Users can control blocking on (1), but should not control on (2) (only manage as https://github.com/ruby/ruby/blob/trunk/doc/ractor.md#L200
 * You can close the incoming port or outgoing port.
   * You can close then with `Ractor#close_incoming` and `Ractor#close_outgoing`.
   * If the incoming port is closed for a Ractor, you can't `send` to the Ractor. If `Ractor.receive` is blocked for the closed incoming port, then it will raise an exception.
-  * If the outgoing port is closed for a Ractor, you can't call `Ractor#take` and `Ractor.yield` on the Ractor. If `Ractor#take` is blocked for the Ractor, then it will raise an exception.
+  * If the outgoing port is closed for a Ractor, you can't call `Ractor#take` and `Ractor.yield` on the Ractor. If ractors are blocking by `Ractor#take` or `Ractor.yield` (... truncated)

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]