In November of last year, I wrote Richard Stallman’s political discourse on sex, which argues that Richard Stallman, the founder of and present-day voting member of the board of directors of the Free Software Foundation (FSF), endorses and advocates for a ha…
via Drew DeVault's blogAside for when implemented correctly and when really needed, multi-threading is often a go to for lazy or amateur developers with an uneducated perception that it would boost performance and make the program run faster.
There was a guy who used to ask me to review his code, nothing fancy, just some stuff he wrote to practice programming. Every code base he sent for review had for some reason the same boiler plate for “multi-threading” which I did not even bother to see if it was at least done “properly” as I always rolled my eyes when I see the mess. One project literally was bound to REST rate limits, but he still bombarded the API with thousands of requests each sent in its own thread, because he genuinely believed that it was helping.
Spawning threads is effortless, synchronizing them is difficult. You will have to worry about race conditions, dead locks, while maintenance and debugging cost increases, and turn the project harder to test and conceptualize. Not a fun time, threading should be at the bottom of the list of optimization routes. In fact, this could hurt performance, if multiple threads interact with a shared object, they’ll block each other, effectively rendering them useless. Additionally, threaded programs are more prone to cache misses, due to cache invalidation after a context switch, trashing out hardware level optimization years of engineering tried to squeeze out.
I am all for simplicity, so single-threading when possible is welcomed. But first, we need to know when threads are commonly used, in which I can think of two situations: waiting for I/O or offloading heavy operations where blocking the main thread for a period of time is not an option.
If your threads do nothing but wait for something to happen and act upon it, you’ll be better off relying on an event loop. Consider libevent or write your own. Your target operating system should offer methods for I/O multiplexing, non-blocking calls and asynchronous I/O, so take advantage of those as well. For the other case where the task is indeed CPU-bound, I honestly have no problem with using threads here.
Keep it simple, your initial solution should not involve more threads. Avoid this unwanted complexity, and give it some thoughts on how to approach it when you’re out of choice.