Bird
Raised Fist0
Rubyprogramming~7 mins

Ractor for true parallelism in Ruby

Choose your learning style10 modes available
Introduction

Ractor lets Ruby run code truly at the same time on multiple CPU cores. This helps programs run faster by doing many things together.

When you want to speed up a program by doing tasks at the same time.
When you have heavy calculations that can be split into parts.
When you want to avoid waiting for one task to finish before starting another.
When you want to use multiple CPU cores efficiently.
When you want to keep your program responsive while doing background work.
Syntax
Ruby
ractor = Ractor.new do
  # code to run in parallel
  result = some_work
  Ractor.yield(result) # send result back
end

value = ractor.take # get result from ractor

Ractor.new creates a new parallel task.

Use Ractor.yield to send data back from inside the ractor.

Examples
This example creates a ractor that calculates 5 times 5 and sends back 25.
Ruby
ractor = Ractor.new do
  5 * 5
end

result = ractor.take
puts result
This ractor sums numbers from 1 to 10 and returns the total.
Ruby
ractor = Ractor.new do
  sum = 0
  (1..10).each { |n| sum += n }
  sum
end

puts ractor.take
This example shows how to send a message back using Ractor.yield.
Ruby
ractor = Ractor.new do
  Ractor.yield("Hello from ractor")
end

message = ractor.take
puts message
Sample Program

This program shows how to use a ractor to calculate squares of numbers from 1 to 5 in parallel. The main program prints messages before and after getting the result.

Ruby
puts "Main program starts"

# Create a ractor to calculate squares of numbers
square_ractor = Ractor.new do
  squares = []
  (1..5).each do |number|
    squares << number * number
  end
  squares
end

# Main program continues while ractor works
puts "Doing other work in main thread..."

# Get result from ractor
result = square_ractor.take
puts "Squares calculated in ractor: #{result}"

puts "Main program ends"
OutputSuccess
Important Notes

Time complexity depends on the task inside the ractor, but using ractors can speed up multi-core processing.

Space complexity includes the memory used by the ractor and its data.

Common mistake: Trying to share mutable objects between ractors causes errors. Use message passing instead.

Use ractors when you need true parallelism. For simple concurrency, threads might be enough.

Summary

Ractors let Ruby run code truly in parallel on multiple CPU cores.

Use Ractor.new to create a parallel task and Ractor.yield or take to communicate.

Ractors help speed up programs by doing work at the same time safely.

Practice

(1/5)
1. What is the main purpose of using Ractor in Ruby?
easy
A. To run code truly in parallel on multiple CPU cores
B. To create graphical user interfaces
C. To handle database connections
D. To write single-threaded scripts

Solution

  1. Step 1: Understand Ractor's role

    Ractor is designed to enable true parallel execution in Ruby, using multiple CPU cores.
  2. Step 2: Compare options

    Options A, B, and C do not relate to parallelism or CPU core usage.
  3. Final Answer:

    To run code truly in parallel on multiple CPU cores -> Option A
  4. Quick Check:

    Ractor = true parallelism [OK]
Hint: Ractor means real parallel tasks in Ruby [OK]
Common Mistakes:
  • Confusing Ractor with threads
  • Thinking Ractor is for UI or database
  • Assuming Ractor runs code sequentially
2. Which of the following is the correct way to create a new Ractor in Ruby?
easy
A. Ractor.new { puts 'Hello from Ractor' }
B. Thread.new { puts 'Hello from Ractor' }
C. Process.spawn { puts 'Hello from Ractor' }
D. Fiber.new { puts 'Hello from Ractor' }

Solution

  1. Step 1: Identify Ractor creation syntax

    Ractor is created using Ractor.new with a block of code to run in parallel.
  2. Step 2: Eliminate other options

    Thread, Process, and Fiber are different concurrency tools, not Ractor.
  3. Final Answer:

    Ractor.new { puts 'Hello from Ractor' } -> Option A
  4. Quick Check:

    Use Ractor.new to create Ractors [OK]
Hint: Ractor.new starts a parallel task [OK]
Common Mistakes:
  • Using Thread.new instead of Ractor.new
  • Confusing Process.spawn with Ractor
  • Using Fiber.new which is cooperative, not parallel
3. What will be the output of this Ruby code using Ractor?
r = Ractor.new { 5 * 5 }
result = r.take
puts result
medium
A. RactorError
B. 5 * 5
C. nil
D. 25

Solution

  1. Step 1: Understand Ractor block execution

    The block { 5 * 5 } runs inside the Ractor and returns 25.
  2. Step 2: Use take to get the result

    r.take receives the value returned by the Ractor block, which is 25.
  3. Final Answer:

    25 -> Option D
  4. Quick Check:

    Ractor returns 25, take receives it [OK]
Hint: Ractor block returns value, take fetches it [OK]
Common Mistakes:
  • Expecting string '5 * 5' instead of calculation
  • Confusing take with yield
  • Assuming nil or error without communication
4. Identify the error in this Ractor code snippet:
r = Ractor.new do
  Ractor.yield 10
  20
end
puts r.take
puts r.take
medium
A. Ractor.new requires arguments
B. Second r.take call will cause Ractor::Closed error
C. No error, code runs fine
D. Calling Ractor.yield inside Ractor block is invalid

Solution

  1. Step 1: Understand Ractor.yield and r.take

    Ractor.yield sends a value to the main thread, and r.take receives it. The first r.take gets 10.
  2. Step 2: Analyze second r.take call

    The block returns 20 after yield, which is the final value. The second r.take gets 20. After that, the Ractor is closed. A third r.take would cause error, but here only two calls are made, so no error.
  3. Step 3: Check the code carefully

    Both r.take calls are valid; no error occurs.
  4. Final Answer:

    No error, code runs fine -> Option C
  5. Quick Check:

    Ractor.yield and take work twice safely [OK]
Hint: Ractor.yield sends values, take receives them sequentially [OK]
Common Mistakes:
  • Thinking Ractor.yield is invalid inside Ractor
  • Expecting error on second take call
  • Assuming Ractor.new needs arguments
5. You want to sum numbers from 1 to 100 using two Ractors running in parallel, each summing half the range. Which code correctly implements this?
hard
A. r1 = Ractor.new { (1..100).sum } r2 = Ractor.new { (1..100).sum } puts r1.take + r2.take
B. r1 = Ractor.new { (1..50).sum } r2 = Ractor.new { (51..100).sum } puts r1.take + r2.take
C. r1 = Thread.new { (1..50).sum } r2 = Thread.new { (51..100).sum } puts r1.value + r2.value
D. r1 = Ractor.new { (1..50).reduce(:+) } r2 = Ractor.new { (51..100).reduce(:+) } puts r1.take * r2.take

Solution

  1. Step 1: Split the range correctly

    We want two Ractors, one summing 1 to 50, the other 51 to 100.
  2. Step 2: Check the operations and combining results

    r1 = Ractor.new { (1..50).sum } r2 = Ractor.new { (51..100).sum } puts r1.take + r2.take sums each half and adds results correctly. r1 = Ractor.new { (1..100).sum } r2 = Ractor.new { (1..100).sum } puts r1.take + r2.take sums full range twice (wrong). r1 = Thread.new { (1..50).sum } r2 = Thread.new { (51..100).sum } puts r1.value + r2.value uses Thread, not Ractor. r1 = Ractor.new { (1..50).reduce(:+) } r2 = Ractor.new { (51..100).reduce(:+) } puts r1.take * r2.take multiplies sums instead of adding.
  3. Final Answer:

    r1 = Ractor.new { (1..50).sum } r2 = Ractor.new { (51..100).sum } puts r1.take + r2.take -> Option B
  4. Quick Check:

    Split range, sum halves, add results [OK]
Hint: Split work, sum halves in Ractors, then add [OK]
Common Mistakes:
  • Using Thread instead of Ractor
  • Summing full range twice
  • Multiplying sums instead of adding
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard