互斥锁 实现同步
互斥锁保证在同一时刻,只有一个线程可以访问共享资源,从而实现了线程同步。
思路
1 创建互斥锁(1个)
pthread_mutex_t mutex;
2 初始化互斥锁
所有线程开始执行前,pthread_mutex_init(&mutex, NULL);
3 创建线程(5个)
pthread_create(&threads[i], NULL, thread_function, arg);
每个线程函数,临界区开始处用pthread_mutex_lock
加锁,
结束用pthread_mutex_unlock
解锁。
4 等待 threads[i] 结束
pthread_join(threads[i], NULL);
5 销毁互斥锁
pthread_mutex_destroy(&mutex);
代码
#define NUM_THREADS 5pthread_mutex_t mutex;//创建一个互斥锁void *thread_function(void *arg) {int thread_id = *(int *)arg;free(arg);pthread_mutex_lock(&mutex);printf("线程%d\n", thread_id);pthread_mutex_unlock(&mutex);return NULL;
}int main() {pthread_t threads[NUM_THREADS];// 初始化互斥锁pthread_mutex_init(&mutex, NULL);//创建5个线程for (int i = 0; i < NUM_THREADS; i++) {int *arg = malloc(sizeof(int));*arg = i;pthread_create(&threads[i], NULL, thread_function, arg);}//等待 threads[i] 结束for (int i = 0; i < NUM_THREADS; i++) {pthread_join(threads[i], NULL);}// 销毁互斥锁pthread_mutex_destroy(&mutex);return 0;
}
运行结果
信号量 实现同步
互斥锁适用于需要严格互斥的情况,而信号量则提供了更灵活的同步控制。
思路
1 创建信号量(1个)
sem_t semaphore;
2 初始化信号量,初始值为1
sem_init(&semaphore, 0, 1);
3 创建线程(5个)
pthread_create(&threads[i], NULL, thread_function, arg);
每个线程函数,临界区开始处用sem_wait
减少信号量的值,阻塞线程直到值大于0。
结束处用sem_post
增加信号量的值,从而允许其他线程进入临界区。
4 等待 threads[i] 结束
pthread_join(threads[i], NULL);
5 销毁信号量
sem_destroy(&semaphore);
代码
#define NUM_THREADS 5sem_t semaphore;//创建信号量void *thread_function(void *arg) {int thread_id = *(int *)arg;free(arg);sem_wait(&semaphore);printf("线程%d\n", thread_id);sem_post(&semaphore);return NULL;
}int main() {pthread_t threads[NUM_THREADS];// 初始化信号量,初始值为1sem_init(&semaphore, 0, 1);、//创建5个线程for (int i = 0; i < NUM_THREADS; i++) {int *arg = malloc(sizeof(int));*arg = i;pthread_create(&threads[i], NULL, thread_function, arg);}//等待 threads[i] 结束for (int i = 0; i < NUM_THREADS; i++) {pthread_join(threads[i], NULL);}// 销毁信号量sem_destroy(&semaphore);return 0;
}
运行结果
补充说明
信号量的初始值决定了可以同时访问共享资源的线程数量。
设置初始值为1,意味着信号量表现得像互斥锁。
如果需要允许多个线程同时访问,可以设置一个更大的初始值