Multithreading: Using Mutex Locks to Handle Mutual Exclusion of Global Variables
Multiple threads share certain resources from the process's static data segment, such as global variables defined in the main thread. These are naturally accessible by other threads as well.
On Unix and Linux platforms, we use mutex locks to handle mutual exclusion issues related to global variables.
Consider a mutex variable, which is specifically associated with a particular variable.
Data type: pthread_mutex_t
Initialization: pthread_mutex_t macPIB_mutex = PTHREAD_MUTEX_INITIALIZER;
Operations:
int pthread_mutex_lock(pthread_mutex_t *mutex) // Locking function. If the mutex is already locked, this function blocks the program until the lock is released.
int pthread_mutex_unlock(pthread_mutex_t *mutex) // Unlocking function
Mutex variables are suitable for preventing concurrent access to a shared variable. However, when we need to wait for a certain condition to occur, we prefer to sleep rather than continuously poll. In such cases, we can use condition variables.
Consider condition variables:
Data type: pthread_cond_t
Initialization: pthread_cond_t count_cond = PTHREAD_COND_INITIALIZER;
Operations:
int pthread_cond_wait (pthread_cond_t *condptr, pthread_mutex_t *mutexptr)
int pthread_cond_signal (pthread_cond_t *condptr)
Note that we associate a single global variable with both a mutex lock and a condition variable.
When calling pthread_cond_wait, if the mutex is already locked, the thread will sleep and simultaneously release the mutexptr lock.
For detailed explanations, refer to pages 604–606 of UNIX Network Programming.
The above covers mutual exclusion issues when multiple threads access shared variables.
When creating a thread, the main thread often needs to pass parameters to the thread function. Be cautious: do not pass pointers. Instead, pass by value (which is supported via C function call parameter copying), or dynamically allocate memory before passing. See pages 588–589 of UNIX Network Programming for concrete examples.