一 Linux系统中,多线程同步技术主要包括以下几种:
1. **互斥锁(Mutexes)**
- `pthread_mutex_t` 是最常用的互斥锁类型,它确保同一时间只有一个线程可以进入临界区,其他试图进入的线程将被阻塞直至锁被释放。
#include <pthread.h>
pthread_mutex_t mtx;
pthread_mutex_init(&mtx, NULL);
void critical_section() {
pthread_mutex_lock(&mtx);
// 临界区代码...
pthread_mutex_unlock(&mtx);
}
2. **自旋锁(Spinlocks)**
- `pthread_spinlock_t` 类似于互斥锁,但是当锁被占用时,等待锁的线程会循环等待(自旋),而不是进入睡眠状态。自旋锁适用于持有时间非常短的情况,否则会导致CPU使用率过高。
pthread_spinlock_t spinlock;
pthread_spin_init(&spinlock, 0);
void spin_critical_section() {
pthread_spin_lock(&spinlock);
// 临界区代码...
pthread_spin_unlock(&spinlock);
}
3. **信号量(Semaphores)**
- `sem_t` 结构体表示信号量,可以用来控制资源的数量,允许一定数量的线程同时访问资源。
sem_t semaphore;
sem_init(&semaphore, 0, MAX_CONCURRENT_THREADS);
void access_resource() {
sem_wait(&semaphore);
// 访问共享资源...
sem_post(&semaphore);
}
4. **条件变量(Condition Variables)**
- `pthread_cond_t` 结合互斥锁使用,线程在条件不满足时可以等待,直到其他线程修改了条件并发出信号唤醒等待的线程。
pthread_mutex_t mtx;
pthread_cond_t cond;
pthread_mutex_init(&mtx, NULL);
pthread_cond_init(&cond, NULL);
void wait_condition() {
pthread_mutex_lock(&mtx);
while (!condition_is_met()) {
pthread_cond_wait(&cond, &mtx);
}
// 条件满足时执行的代码...
pthread_mutex_unlock(&mtx);
}
void signal_condition() {
pthread_mutex_lock(&mtx);
// 修改条件...
pthread_cond_signal(&cond); // 或者 pthread_cond_broadcast(&cond);
pthread_mutex_unlock(&mtx);
}
5. **读写锁(Reader-Writer Locks)**
- `pthread_rwlock_t` 读写锁允许多个线程同时读取资源,但在写入时会排斥所有的读取和写入。
pthread_rwlock_t rwlock;
pthread_rwlock_init(&rwlock, NULL);
void read_access() {
pthread_rwlock_rdlock(&rwlock);
// 读取资源...
pthread_rwlock_unlock(&rwlock);
}
void write_access() {
pthread_rwlock_wrlock(&rwlock);
// 写入资源...
pthread_rwlock_unlock(&rwlock);
}
6. **原子操作(Atomic Operations)**
- Linux内核提供了原子操作API,例如`atomic_t`类型,用于对整数变量进行原子的增加、减少、交换等操作,避免多线程环境下的数据竞争。
此外,Linux内核层面还支持其他的同步原语,例如seqlock、RCU(Read-Copy Update)等,这些都是用于解决特定场景下的同步问题。在用户空间编程时,POSIX线程库提供的接口足以满足大多数多线程同步需求。而在内核编程中,可能会用到更底层和专用的同步机制。
二 在Linux系统中,多线程同步技术主要包括互斥锁(Mutex)、信号量(Semaphore)、条件变量(Condition Variable)、读写锁(Read-Write Lock)、自旋锁(Spinlock)、原子操作(Atomic Operations)和屏障(Barrier)。以下是这些同步技术在Linux系统中的实际使用例子:
1. **互斥锁(Mutex)**:
#include <pthread.h>
#include<stdio.h>
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
int counter = 0;
void* thread_function(void* arg) {
for (int i = 0; i < 100000; i++) {
pthread_mutex_lock(&mutex);
counter++;
pthread_mutex_unlock(&mutex);
}
return NULL;
}
int main() {
pthread_t thread1, thread2;
pthread_create(&thread1, NULL, thread_function, NULL);
pthread_create(&thread2, NULL, thread_function, NULL);
pthread_join(thread1, NULL);
pthread_join(thread2, NULL);
printf("Counter: %d\n", counter);
return 0;
}
2. **信号量(Semaphore)**:
#include <pthread.h>
#include <semaphore.h>
#include<stdio.h>
sem_t sem;
int counter = 0;
void* thread_function(void* arg) {
for (int i = 0; i < 100000; i++) {
sem_wait(&sem);
counter++;
sem_post(&sem);
}
return NULL;
}
int main() {
sem_init(&sem, 0, 1);
pthread_t thread1, thread2;
pthread_create(&thread1, NULL, thread_function, NULL);
pthread_create(&thread2, NULL, thread_function, NULL);
pthread_join(thread1, NULL);
pthread_join(thread2, NULL);
printf("Counter: %d\n", counter);
sem_destroy(&sem);
return 0;
}
3. **条件变量(Condition Variable)**:
#include <pthread.h>
#include<stdio.h>
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
int counter = 0;
void* thread_function(void* arg) {
pthread_mutex_lock(&mutex);
counter++;
pthread_cond_signal(&cond);
pthread_mutex_unlock(&mutex);
return NULL;
}
int main() {
pthread_t thread;
pthread_create(&thread, NULL, thread_function, NULL);
pthread_mutex_lock(&mutex);
while (counter == 0) {
pthread_cond_wait(&cond, &mutex);
}
pthread_mutex_unlock(&mutex);
printf("Counter: %d\n", counter);
pthread_join(thread, NULL);
return 0;
}
4. **读写锁(Read-Write Lock)**:
#include <pthread.h>
#include<stdio.h>
pthread_rwlock_t rwlock = PTHREAD_RWLOCK_INITIALIZER;
int counter = 0;
void* read_thread_function(void* arg) {
pthread_rwlock_rdlock(&rwlock);
printf("Counter: %d\n", counter);
pthread_rwlock_unlock(&rwlock);
return NULL;
}
void* write_thread_function(void* arg) {
pthread_rwlock_wrlock(&rwlock);
counter++;
pthread_rwlock_unlock(&rwlock);
return NULL;
}
int main() {
pthread_t read_thread, write_thread;
pthread_create(&read_thread, NULL, read_thread_function, NULL);
pthread_create(&write_thread, NULL, write_thread_function, NULL);
pthread_join(read_thread, NULL);
pthread_join(write_thread, NULL);
return 0;
}
5. **自旋锁(Spinlock)**:
自旋锁通常用于内核编程,而不是用户空间程序。在用户空间程序中,使用互斥锁和其他同步原语通常更为合适。
6. **原子操作(Atomic Operations)**:
#include<stdio.h>
#include <stdbool.h>
int counter = 0;
void atomic_increment(int* value) {
int old_value, new_value;
do {
old_value = *value;
new_value = old_value + 1;
} while (!__sync_bool_compare_and_swap(value, old_value, new_value));
}
int main() {
for (int i = 0; i < 100000; i++) {
atomic_increment(&counter);
}
printf("Counter: %d\n", counter);
return 0;
}
7. **屏障(Barrier)**:
#include <pthread.h>
#include<stdio.h>
pthread_barrier_t barrier;
void* thread_function(void* arg) {
printf("Thread %ld before barrier\n", (long)arg);
pthread_barrier_wait(&barrier);
printf("Thread %ld after barrier\n", (long)arg);
return NULL;
}
int main() {
pthread_barrier_init(&barrier, NULL, 3);
pthread_t thread1, thread2;
pthread_create(&thread1, NULL, thread_function, (void*)1);
pthread_create(&thread2, NULL, thread_function, (void*)2);
printf("Main thread before barrier\n");
pthread_barrier_wait(&barrier);
printf("Main thread after barrier\n");
pthread_join(thread1, NULL);
pthread_join(thread2, NULL);
pthread_barrier_destroy(&barrier);
return 0;
}
这些实际使用例子展示了如何在Linux系统中使用不同的多线程同步技术。在实际编程中,可以根据具体需求选择合适的同步机制。