在 Linux 中,实现临界区的常用方法有以下几种:
1. 自旋锁(Spinlock):自旋锁是最基本的同步机制之一,它通过忙等待的方式来实现对临界区的访问控制。适用于临界区持有时间较短的场景。
2. 互斥锁(Mutex):互斥锁是较为复杂的同步机制,当一个线程获得锁时,其他线程将被阻塞。当临界区持有时间较长时,使用互斥锁可以避免 CPU 资源的浪费。
3. 读写锁(Rwlock):读写锁区分读操作和写操作,多个读操作可以并发执行,但写操作是互斥的。适用于读多写少的场景。
4. 信号量(Semaphore):信号量是一种通用的同步机制,可以用来实现各种同步需求,如限制并发访问的数量等。
5. 条件变量(Condition):条件变量是一种更加复杂的同步机制,它允许线程在满足某个条件时被唤醒,从而避免了无谓的等待。
下面给出一个互斥锁实现临界区的示例代码:
```c
#include
#include
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
int counter = 0;
void* worker_function(void* arg) {
for (int i = 0; i < 1000000; i++) {
pthread_mutex_lock(&mutex);
counter++;
pthread_mutex_unlock(&mutex);
}
return NULL;
}
int main() {
pthread_t thread1, thread2;
pthread_create(&thread1, NULL, worker_function, NULL);
pthread_create(&thread2, NULL, worker_function, NULL);
pthread_join(thread1, NULL);
pthread_join(thread2, NULL);
printf("Final counter value: %d\n", counter);
return 0;
}
```
在这个示例中,我们使用 `pthread_mutex_t` 类型的互斥锁来保护临界区,确保 `counter` 变量的访问是互斥的。当一个线程获得锁时,其他线程将被阻塞,直到该线程释放锁。