Executors 101

Written by

in

Executors

So what are executors? Executors sit between tasks and their execution context, the way iterators sit between collections and algorithms. Executors could potentially do many things, for example:

  • parallelize tasks (over multiple cores, for example)
  • distribute tasks (over multiple machines or to GPUs, for example)
  • sequence tasks (stitch tasks together over time)
  • prioritize tasks (a task scheduled at a fixed time might trump a deferred task)

My take on multi-threading

  • apply the rule of zero (mutexes)
  • apply the motto: there can be only one! (thread)

Multi-threading 101 in a nutshell: if you can avoid it, do so.

Why, you might ask?

Some attributes of multi-threaded code:

  • difficult to get right (write)
  • difficult to understand (read)
  • difficult to debug
  • difficult to unit test

These are not good attributes for code to have in general. So is multi-threaded code evil? No, not by itself, but given these attributes it is better to avoid it if possible. Are there scenarios where multi-threading cannot be avoided? At first glance it would seem so:

  • when interacting with or monitoring a component that does not support events
  • when a system must remain responsive and execute long-running tasks at the same time

However, depending on how much control you have over the component, it can be avoided in both cases. (To do: describe how.)

Concurrency vs parallelism

As defined by Hartmut Kaiser:

  • Concurrency: more than one thread is operating on the same dataset.
  • Parallelism: threads do work independently, on separate datasets.

Unfinished… to be continued.

References

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *