操作系统知识速记:实现线程同步的方式
操作系统知识速记:实现线程同步的方式
在当今的多核和多线程世界里,线程同步是确保数据一致性和提高系统性能的关键。
互斥锁(Mutex)
互斥锁是实现线程安全的基础。它通过确保同一时间只有一个线程能访问共享资源来防止数据竞争。以下是互斥锁的基本示例:
pthread_mutex_t lock;
pthread_mutex_lock(&lock);
// 访问共享资源
pthread_mutex_unlock(&lock);
在这个例子中,当一个线程获得锁时,其他线程必须等待,直到锁被释放。互斥锁适用于要求严格的资源管理场景。
信号量(Semaphore)
信号量是一种更灵活的同步机制,允许多个线程同时访问共享资源。信号量通过维护一个计数器来控制线程的访问。以下是信号量的基本用法:
sem_t sem;
sem_wait(&sem); // 值减一,若小于0则阻塞
// 访问共享资源
sem_post(&sem); // 值加一
在此示例中,sem_wait
会阻塞直到其他线程释放资源,适合用于多生产者-多消费者模型的场景。
条件变量(Condition Variable)
条件变量使得线程可以在某条件不满足时挂起,并在条件满足时被其他线程通知。使用条件变量的基本步骤如下:
pthread_cond_t cond;
pthread_mutex_t lock;
// 等待条件
pthread_mutex_lock(&lock);
pthread_cond_wait(&cond, &lock);
pthread_mutex_unlock(&lock);
// 条件满足后通知
pthread_cond_signal(&cond);
在这里,线程会等待直到被其他线程通过pthread_cond_signal
通知。条件变量适合于需要动态响应的场景,如生产者-消费者问题。
读写锁(Read-Write Lock)
读写锁允许多个线程同时读取共享数据,但在写线程进行写操作时,其他读写线程必须等待。这种锁的使用场景主要是大多数操作为读的情况。示例如下:
pthread_rwlock_t rwlock;
pthread_rwlock_rdlock(&rwlock); // 读锁
// 读取共享资源
pthread_rwlock_unlock(&rwlock); // 解锁
pthread_rwlock_wrlock(&rwlock); // 写锁
// 写共享资源
pthread_rwlock_unlock(&rwlock); // 解锁
这样设计可以在同时存在多个读者的情况下提高性能。
自旋锁(Spinlock)
自旋锁是一种轻量级锁,适用于持锁时间极短的场景。获取自旋锁的线程不会进入睡眠状态,而是一直循环检测锁状态。示例代码如下:
while (__atomic_test_and_set(&lock, __ATOMIC_ACQUIRE)); // 获取锁
// 访问共享资源
__atomic_clear(&lock, __ATOMIC_RELEASE); // 解锁
自旋锁虽然开销小,但如果持锁时间过长,可能会导致CPU资源的浪费。
综述表
同步方式 | 特点 | 适用场景 |
---|---|---|
互斥锁 | 单线程访问共享资源 | 资源需要严格互斥的场景 |
信号量 | 控制访问数量 | 多生产者-多消费者场景 |
条件变量 | 线程等待特定条件 | 动态条件响应的场景 |
读写锁 | 允许多个读者,有效提高并发度 | 大部分为读,少数为写的场景 |
自旋锁 | 轻量级锁,消耗CPU时间 | 持锁时间极短的情况 |