Step 2 - Multiple Coroutines

Lets take a look at a call flow calling multiple coroutines concurrently.

def generator():
    # do something
    yield # something
    # do something else
    yield # something else
    # do another thing
    return # some value

def other_generator():
    # do something
    yield # something
    # do something else
    return # other value


gen1 = generator()
next(gen1)
gen2 = other_generator()
next(gen1)
next(gen2)
try:
    next(gen1)
except StopIteration as e:
    some_value = e.value
try:
    next(gen2)
except StopIteration as e:
    other_value = e.value
        sequenceDiagram
  participant c as Caller
  participant g1 as Generator
  participant g2 as Other Generator
  activate c
  activate c
  c->>g1: send/next
  deactivate c
  activate g1
  activate g1
  g1-->>c: yield
  deactivate g1
  activate c
  c->>g2: send/next
  deactivate c
  activate g2
  activate g2
  g2-->>c: yield
  deactivate g2
  activate c
  c->>g1: send/next
  deactivate c
  activate g1
  g1-->>c: yield
  deactivate g1
  activate c
  c->>g1: send/next
  deactivate c
  activate g1
  g1->>c: return/StopIteration
  deactivate g1
  deactivate g1
  activate c
  c->>g2: send/next
  deactivate c
  activate g2
  g2->>c: return/StopIteration
  deactivate g2
  deactivate g2
  deactivate c
    

Summary

  • The caller can use several coroutines concurrently.

  • The caller is in control which coroutine and when a coroutine is resumed.

  • The caller needs to catch the StopIteration exception of each coroutine to get the return values.