5

Context: Recently I was discussing the design of a small programme with a new team member (I am the product manager). The programme is essentially a protocol converter that reads data from a number of sockets (as a client) and inserts that data into the database. We discussed the idea of having one thread per socket to allow the programme to scale to more sockets without blocking itself. The same team member then discussed this (in general terms) with a senior dev who gave him the advice "threads should only ever block on one thing" i.e. if the same thread can block in two places, it should be two threads.

In the context of my programme, this would mean two threads per socket, or possibly one thread per socket plus one that does all the database insertions.

However, my question is not about my programme specifically but about the advice "threads should only ever block on one thing" - is this good advice to give to someone? Is it a well-known best practice? Or perhaps it derives from a particular school of thought or programming paradigm.

4
  • Maybe threads should never block. docs.microsoft.com/en-us/dotnet/csharp/programming-guide/…
    – Erik Eidt
    Jan 2, 2021 at 16:50
  • Surely async programmes block on the await statement? And async coroutines will still block internally on I/O?
    – SimonN
    Jan 2, 2021 at 17:30
  • Upon await, async methods return to their caller. That thread is free to do other work, i.e. the thread is not blocked. It makes better use of a thread, We can also mix async/await with multi threading.
    – Erik Eidt
    Jan 2, 2021 at 18:28
  • Thanks I'll read up on async (asyncio for me as my personal projects are in Python although the example in question is Java)
    – SimonN
    Jan 2, 2021 at 20:58

2 Answers 2

5

This advice sounds like "threads should do only simple things". And what is meant with blocking: locking? or simply locking?

Threads are in general waiting for input to be processed (they are blocked as long as no input is coming) or for scarce processing resources (e.g. blocked in a waiting state as long as CPU, other hardware resources are not available). Moreover when several threads need to cooperate (e.g. share a common data structure) synchronisation operation may keep threads in a waiting states (e.g. on a mutex to be unlocked).

There was a lot of work done on avoiding deadlocks with multiple mutexes: it is not without reason! Blocking on a single mutex is for the simple cases (fortunately most of the daily problems) but some problems just cannot be solved with a single mutex.

Lastly, the graal of multithread processing is to avoid blocking at all, by using lock free structured. But while it may appear a great an easy idea, it is a very complex and error-prone task to design such a structure.

So in conclusion: there is ni reason that a thread should block only on a single thing. It is however true that blocking on a single thing prevents some common error situations (e.g. deadlocks) even if it’s not the only way to prevent such adverse outcome.

2

"threads should only ever block on one thing"

That's a very restrictive guideline that can indeed guarantee deadlock-free multi-threading.

If threads block on multiple things, you have to make sure that no deadlocks can arise, e.g. by analyzing the block-object nesting graph and making sure that it's cycle-free. In many relevant cases, that's an easy task, easier than trying to split a thread into two just to avoid blocking on multiple objects.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.