In Linux, process and thread synchronization is achieved through various mechanisms, including mutexes, semaphores, and condition variables.
A mutex is a binary semaphore that is used to provide mutual exclusion to a critical section of code. It is typically used to protect shared resources from concurrent access by multiple threads or processes. A mutex can be locked and unlocked by a thread or process, and only one thread or process can hold the lock at any given time. If another thread or process attempts to acquire the lock while it is already held, it will block until the lock is released.
An example of using a mutex in C code is:
#include <pthread.h>
pthread_mutex_t lock;
void *thread_function(void *arg)
{
// Acquire the lock
pthread_mutex_lock(&lock);
// Access shared resource
// ...
// Release the lock
pthread_mutex_unlock(&lock);
return NULL;
}
A semaphore is a more general synchronization mechanism that can be used to control access to a shared resource by multiple threads or processes. Unlike a mutex, a semaphore can have multiple states, and each state corresponds to a different number of resources that are available for use. A semaphore can be used to implement synchronization primitives such as mutexes and condition variables, as well as more complex synchronization schemes.
An example of using a semaphore in C code is:
#include <semaphore.h>
sem_t semaphore;
void *thread_function(void *arg)
{
// Wait for a resource to become available
sem_wait(&semaphore);
// Access shared resource
// ...
// Release the resource
sem_post(&semaphore);
return NULL;
}
A condition variable is a synchronization primitive that is used to signal threads that a particular event has occurred. It is typically used to implement a wait-notify mechanism, where one or more threads wait for a condition to become true before continuing execution. A condition variable is associated with a mutex, and threads must hold the mutex in order to wait on or signal the condition variable.
An example of using a condition variable in C code is:
#include <pthread.h>
pthread_mutex_t lock;
pthread_cond_t cond;
void *thread_function(void *arg)
{
// Acquire the lock
pthread_mutex_lock(&lock);
// Wait for the condition to become true
while (condition == 0) {
pthread_cond_wait(&cond, &lock);
}
// Access shared resource
// ...
// Release the lock
pthread_mutex_unlock(&lock);
return NULL;
}
void signal_function()
{
// Acquire the lock
pthread_mutex_lock(&lock);
// Signal the condition variable
condition = 1;
pthread_cond_signal(&cond);
// Release the lock
pthread_mutex_unlock(&lock);
}
In this example, the thread waits on the condition variable cond while holding the mutex lock. When the condition becomes true, the signal function signals the condition variable, waking up the waiting thread.