Understanding parallelism with coroutines

Hi all. I have been reading through the documentation on coroutines recently. I read over the sections and done some testing and still need some clarification on a concept.

How can coroutines be run in parallel with each other? There is a “concurrent using async” section the api covers , but they use the async keyword to achieve parallelism. Is async even needed for coroutines to run in parallel? If I just did a GlobalScope.launch(){…} for two separate coroutines, would they be run in parallel? (Assuming the computer has more than 1 core that is).

First thing to understand is that parallelism is not the same as concurrency. A machine that has only 1 CPU and 1 thread cannot execute more than 1 task in parallel, but it still can execute more than 1 task concurrently. What is the difference?

Let me show with a Javascript example that runs 2 tasks concurrently. Javascript is a good example, because it inherently has 1 thread only (ignoring Ajax and WebWorker for this example).

function startTasks() {
    startTask("foo");
    startTask("bar");
}

function startTask(name) {
  console.log("starting task " + name);
  enqueuTaskStep(name, 1);
}

function enqueuTaskStep(name, step) {
  window.setTimeout(function() {
    taskStep(name, step);
  }, 1);
}

function taskStep(name, step) {
  console.log(name + " step " + step);
  if (step == 10) {
    console.log(name + " finished");
    return;
  }
  enqueuTaskStep(name, step+1);
}

Executing the startTasks function will start 2 tasks concurrently. This is what will be printed in console:

starting task foo
starting task bar
foo step 1
bar step 1
foo step 2
bar step 2

foo step 9
bar step 9
foo step 10
foo finished
bar step 10
bar finished

As can be seen, the tasks are printing to the console concurrently, akthough they are executed on the same thread.

This might seem a little off topic, but understanding this is fundamental in understanding the core power of coroutines. I am not saying that you cannot do real parallel stuff that involves multi-threading with coroutines. You sure can. But not every concurrent coroutine necessarily starts parallel threads, and the core power of coroutines is independent of threads.

To give a concrete answer to your last question, I would need to see more concrete code. Because the answer depends on how you start the coroutines.

The difference between launch and async is that a coroutine started with async returns a value. If you don’t need to return a value then you can use launch.