concurrency call to arms

John Belmonte john at neggie.net
Tue Aug 28 03:36:04 UTC 2018


On Wednesday, 22 August 2018 at 16:49:01 UTC, Russel Winder wrote:
> Have you tried asyncio in the Python standard library? Is Trio 
> better?

The library that Guido admits is a disaster?  
https://twitter.com/gvanrossum/status/938445451908472832

Trio and libraries like it have evolved out of frustration with 
asyncio.

>>      with open_task_container() as container:
>>          container.start_task(a)
>>          container.start_task(b)
>>          await sleep(1)
>>          container.start_task(c)
>>          # end of with block
>> 
>>      # program continues (tasks a, b, c must be completed)...
>
> Assuming a, b, and c run in parallel and this is just a nice 
> Pythonic
> way of ensuring join, this is fairly standard fork/join thread 
> pool
> task management

It's far more than "ensuring join".  It ensures that tasks 
created by children are similarly constrained.  It allows the 
normal try-catch of exceptions coming from any level of child 
tasks.  It ensures that when a task has an error, all sibling 
tasks are cancelled and the resulting multi-exception is 
propagated to the parent.

> – except Python is single threaded so the above is time
> division multiplexing of tasks.

No, tasks can optionally be real threads (obviously constrained 
by GIL).  Soon they can be tasks from the "multiprocessing" 
library as well (separate process, either local or remote).

These are details of Trio's implementation and Python.  As 
mentioned, the control structures apply to any concurrency model 
(implicit or explicit context switching, OS or light threads, 
etc.)

> I've not followed async/await in C# but in Python it is a tool 
> for concurrency but clearly not for parallelism. Sadly 
> async/await has become a fashion that means it is being forced 
> into programming languages that really do not need it.

async/await is a means to explicitly mark points of context 
switching in API's and code.  It applies to threads, coroutines, 
remote processing, or anything else which may allow something 
else to modify system state while you're waiting.

Local to a single thread, async/await with coroutines happens to 
be wonderful because it eliminates a ton of explicit locking, 
fretting about race conditions, etc. required of the programmer.  
It's a building block-- e.g. you can then combine such threads in 
careful ways with message passing within and among CPU cores to 
get the best of all worlds.

While Go can certainly implement the nursery and cancellation 
control structures, there is no turning back on Go's implicit 
context switching (i.e. any old function call can cause a context 
switch).  The human is back to fretting about locks and race 
conditions, and unable to prove that even the smallest of 
programs is correct.



More information about the Digitalmars-d mailing list