Several locks between multiple threads

1. Mutex (mutual exclusion lock)

2. Read-write lock (shared mutex)

3. Spin lock

4. Condition variables

5. Barrier

1. Mutex (mutual exclusion lock)

#include<pthread.h>

// initialize mutex
int pthread_mutex_init(pthread_mutex_t *restrict mutex, const pthread_mutexattr_t *restrict attr);    

// destroy mutex
int pthread_mutex_destroy(pthread_mutex_t *mutex); 

// lock (thread may block)
int pthread_mutex_lock(pthread_mutex_t *mutex);

// try to lock (thread will not be blocked)
int pthread_mutex_trylock(pthread_mutex_t *mutex);

// unlock
int pthread_mutex_unlock(pthread_mutex_t *mutex);                                                                               
                                    

2. Read-write lock (shared mutex)

A read-write lock can have three states: locked in read mode, locked in write mode, and unlocked. Only one thread can hold the write mode of the read-write lock at a time, but multiple threads can hold the read-write lock of the read mode at the same time. When the read-write lock is write-locked, all threads trying to lock the lock will be blocked until the lock is unlocked. When the read-write lock is in the read-locked state, all threads trying to lock it in read mode can gain access, but any thread that wants to lock the lock in write mode will block until all threads are released. their write locks. Read-write locks are suitable for situations where the reading of data is far greater than the writing.

#include <pthread.h>

// Initialize read-write lock
int pthread_rwlock_init(pthread_rwlock_t *restrict rwlock, const pthread_rwlockattr_t *restrict attr);

// Destroy the read-write lock
int pthread_rwlock_destroy(pthread_rwlock_t *rwlock);

// Read mode lock (blocking mode)
int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock);

// Read mode lock (non-blocking mode)
int pthread_rwlock_tryrdlock(pthread_rwlock_t *rwlock);

// Write mode lock (blocking mode)
int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock);

// Write mode lock (non-blocking mode)
int pthread_rwlock_trywrlock(pthread_rwlock_t *rwlock);

// unlock
int pthread_rwlock_unlock(pthread_rwlock_t *rwlock);

3. Spin lock

Spin locks are similar to mutexes, busy waiting (spin) blocking instead of sleep blocking. Spinlocks are for the time-end of holding, and the thread doesn't want to spend too much on rescheduling. It is mostly used in kernel mode and less in user mode.

#include <pthread.h>

// Initialize spinlock
int pthread_spin_init(pthread_spinlock_t *lock);

// destroy spinlock
int pthread_spin_destroy(pthread_spinlock_t *lock);

// lock (blocking mode)
int pthread_spin_lock(pthread_spinlock_t *lock);

// lock (non-blocking mode)
int pthread_spin_trylock(pthread_spinlock_t *lock);

// unlock
int pthread_spin_unlock(pthread_spinlock_t *lock);

4. Condition variables

Condition variables are another synchronization mechanism available to threads. Condition variables are used in conjunction with mutexes to allow threads to wait for a specific condition to occur in a race-free manner. Mainly used in thread pool . The condition itself is protected by a mutex, and the thread must first lock the mutex before changing the condition.

#include <pthread.h>

// Initialize the condition variable
int pthread_cond_init(pthread_cond_t *restrict cond, const pthread_condattr_t *restrict attr);

// The destruction condition will come to you
int pthread_cond_destroy(pthread_cond_t cond);

// Wait for the condition to occur (the caller passes the locked mutex to the function, the function puts the calling thread on the list of threads waiting for the condition, and unlocks the mutex for you)
int pthread_cond_wait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex);

// timeout specifies how long we are willing to wait
int pthread_cond_timedwait(pthread_cond_t *restrict cond, pthread_mutex_t *restrict mutex, cond struct timespec *restrict timeout);

// Triggers a thread waiting on the condition
int pthread_cond_signal(pthread_cond_t cond);

// triggers all threads waiting on the condition
int pthread_cond_broadcast(pthread_cond_t cond);


5. Barrier

A barrier is a synchronization mechanism for coordinating the work of multiple processes in parallel. A barrier allows each thread to wait until all cooperating threads have reached a certain point, and then resume execution from that point.

#include<pthread.h>

// barrier initialization
int pthread_barrier_init(pthread_barrier_t *restrict barrier, const pthread_barrierattr_ty * restrict attr, unsigned int count); 

// Barrier Destruction
int pthread_barrier_destroy(pthread_barrier_t *barrier);

// The thread blocks to the barrier, if the last thread calling the function satisfies the barrier count, all threads are woken up
int pthread_barrier_wait(pthread_barrier_t *barrier);

 

Tags: Linux

Posted by ozestretch on Sun, 01 May 2022 23:12:26 +0300