class

Fiber::ExecutionContext::Concurrent

Inherits Fiber::ExecutionContext::Parallel / Fiber::ExecutionContext / Reference / Object

Concurrent-only execution context.

Fibers running in the same context can only run concurrently and never in parallel to each others. However, they still run in parallel to fibers running in other execution contexts.

Fibers in this context can use simpler and faster synchronization primitives between themselves (for example no atomics or thread safety required), but data shared with other contexts needs to be protected (see Sync), and communication with fibers in other contexts requires safe primitives, for example Channel.

A blocking fiber blocks the entire context, and thus all the other fibers in the context.

For example: we can start a concurrent context to run consumer fibers, while the default context produces values. Because the consumer fibers will never run in parallel and don't yield between reading result then writing it, we are not required to synchronize accesses to the value:

require "wait_group"

consumers = Fiber::ExecutionContext::Concurrent.new("consumers")
channel = Channel(Int32).new(64)
wg = WaitGroup.new(32)

result = 0

32.times do
  consumers.spawn do
    while value = channel.receive?
      # safe, but only for this example:
      result = result + value
    end
  ensure
    wg.done
  end
end

1024.times { |i| channel.send(i) }
channel.close

# wait for all workers to be done
wg.wait

p result # => 523776

In practice, we still recommended to always protect shared accesses to a variable, for example using Atomic#add to increment result or a Sync primitive for more complex operations.

NOTE: The Concurrent execution context isn't tied to a system thread, and may switch to another system thread, for example when a fiber is blocked on a syscall.

Constructors

new(name : String) : self

Creates a Concurrent context. The context will only really start when a fiber is spawned into it.

Source

Instance methods

resize(maximum : Int32) : Nil

Always raises an ArgumentError exception because a concurrent context cannot be resized.

Source