Executors 101

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, to name some:

  • parallelize tasks (over multiple cores for example)
  • distribute tasks (over multiple machines or to gpu’s for example)
  • sequentialize tasks (stitch tasks together over time)
  • prioritize tasks (scheduled tasks at a fixed time might trumpf a deferred task)

My take on multi-threading

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

Basically, 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 unittest

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

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

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

concurrency vs parallelism

as defined by Hartmut Kaiser:

concurrency: more then one thread is operating on the same dataset

parallelism: threads that do work independently and on separate datasets

Unfinished… To be continued…

References