Threads and simple Dead lock cure

前端 未结 9 661
余生分开走
余生分开走 2021-01-04 22:48

When dealing with threads (specifically in C++) using mutex locks and semaphores is there a simple rule of thumb to avoid Dead Locks and have nice clean Synchronization?

相关标签:
9条回答
  • 2021-01-04 23:23

    There's no practical cure. Specifically, there's no way to simply test code for being synchronizationally correct, or to have your programmers obey the rules of the gentleman with the green V.

    There's no way to properly test the multithreaded code, because the program logic may depend on timing of locks acquisition, and therefore, be different from execution to execution, somehow invalidating the concept of QA.

    I would say

    • prefer using threads only as a performance optimization for multi-core machines
    • only optimize performance when you are sure you need this performance
    • you may use threads to simplify program logic, but only when you are absolutely sure what you are doing. Be extra careful and all locks are confined to a very small piece of code. Do not let any newbies near such code.
    • never use threads in a mission-critical system, such as flying an aircraft or operating dangerous machinery
    • in all cases, threads are seldom cost-effective, due to higher debug and QA costs

    If you determined to do threads or maintaining existing codebase:

    • confine all locks to small and simple pieces of code, which operate on primitives
    • avoid function calls or getting the program flow away to where the fact of being executed under lock is not immediately visible. This function will change by future authors, widening your lock span without your control.
    • get locks inside objects to reduce locking scope, wrap non-thread-safe 3rd-party objects with your own thread-safe interfaces.
    • never send synchronous notifications (callbacks) when executing under lock
    • use only RAII locks, to reduce the cognitive load when thinking "how else can we exit from here", as in exceptions, etc.

    A few words on how to avoid multi-threading.

    A single-threaded design usually involves some heart-beat function provided by program components, and called in a loop (called heartbeat cycle) which, when called, gives a chance to all components to do the next piece of work and to surrender control back again. What algorithmists like to think of as "loops" inside the components, will turn into state machines, to identify what is the next thing that should be done when called. State is best maintained as member data of respective objects.

    0 讨论(0)
  • 2021-01-04 23:25

    Try to avoid acquiring one lock and trying to acquire another. This can result into circular dependency and cause for deadlock. If it is un-avoidable then at least the order of acquire locks should be predictable.

    Use RAII ( to make sure lock is release properly in case of exception as well)

    0 讨论(0)
  • 2021-01-04 23:26

    One way to ensure the ordering that other folks have talked about is to acquire locks in an order defined by their memory address. If at any point, you try to acquire a lock that should have been earlier in the sequence, you release all the locks and start over.

    With a little work, it's possible to do this nearly automatically with some wrapper classes around the system primitives.

    0 讨论(0)
提交回复
热议问题