Thread synchronisation
Tags: threading, concurrency, parallelism, beginers
Published: 2023-12-30 17:31:05

Thread synchronisation is a critical aspect of multithreading, where multiple threads run concurrently in a program. Without proper synchronisation mechanisms, race conditions and other concurrency issues can arise, leading to unpredictable behaviour and data corruption. 

Here are some common thread synchronisation mechanisms:

### Locks and Mutexes:

**Locks** - A lock is a synchronisation mechanism to control access to a shared resource. Threads must acquire the lock before entering the critical section and release it when done. Only one thread can hold the lock at any given time.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/akc5n830dqgwd783o17e.png)

**Mutex (Mutual Exclusion)** -  A mutex is a type of lock that provides mutual exclusion. It has two states: locked and unlocked. Only one thread can hold the mutex at a time


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qmx8e3tuow5kam5it1lf.png)

### Semaphores:

A semaphore is a synchronisation primitive that controls access to a resource by maintaining a count of the number of threads that can access the resource simultaneously. It allows more than one thread to access the resource at the same time, up to a specified limit.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9cuj5fm44gp9gz8z32uk.png)

### Conditions:

Conditions are synchronisation primitives that allow threads to wait until a certain condition is true. They are often used with locks to coordinate threads. Threads can signal each other to indicate that a condition has changed.

### Barriers:

A barrier is a synchronisation mechanism where a set of threads must wait for each other at a designated point before any of them can proceed. Once all threads have arrived at the barrier, they are released simultaneously.


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/p8w9h96ibus48xgdn98r.png)

### Write Locks:

Read-write locks allow multiple threads to read a shared resource simultaneously, but only one thread can write to the resource at a time. This can improve performance in scenarios where there are more read operations than write operations.

### Atomic Operations:

Atomic operations are operations that are executed in a single, uninterruptible step. Atomic operations are often used for simple, indivisible updates to shared variables, and they help avoid race conditions.

### Thread-local Storage:

Some synchronisation issues can be avoided by using thread-local storage, where each thread has its own copy of data. This eliminates the need for synchronisation when accessing thread-local variables.

### Futures and Promises:

Futures and promises provide a way for one thread to wait for the result of a computation performed by another thread. The future represents the result of a computation, and the promise is used to set the result.

It's important to choose the synchronisation mechanism that best fits the requirements of your application. The choice may depend on factors such as the nature of shared resources, the level of concurrency required, and the complexity of the synchronisation logic. Additionally, care should be taken to avoid deadlocks, live-locks, and other pitfalls associated with concurrent programming.