C语言Pthread互斥锁9读1写场景未生效,求助锁函数正确调用位置
Pthread互斥锁异常问题排查与修复
根因分析
Pthread互斥锁是协作式同步原语,不会自动为共享资源加上访问屏障,只有所有访问共享资源的线程都主动申请持有锁,才能保证互斥访问。
你当前代码的问题仅出在读线程侧:9个读线程访问共享数组array时没有申请锁,直接读取内存数据,自然能读到写线程持有锁修改过程中的中间状态(数组元素被置0但还未回填正确值的状态)。
互斥锁正确调用方式
所有访问共享资源(本次示例中是array数组)的线程,无论读、写操作,都必须遵循如下执行流程:
- 访问共享资源前调用
pthread_mutex_lock(&lock)申请锁 - 访问共享资源
- 访问结束后立即调用
pthread_mutex_unlock(&lock)释放锁
你现有代码中写线程的锁调用位置是正确的,已经完整覆盖了数组修改的原子区间,仅需要补充读线程的加锁逻辑即可。
修正后可运行代码
#include <pthread.h> #include <stdio.h> #include <unistd.h> #include <string.h> #include <time.h> #include <stdlib.h> #define NUM_THREADS 10 pthread_mutex_t lock; int array[1000] = {0}; pthread_t threads[NUM_THREADS]; int change_array(int *array) { int arrayhelper[1000] = {0}; for (int i = 0; i < 1000; ++i) arrayhelper[i] = i; pthread_mutex_lock(&lock); for (int i = 0; i < 1000; ++i) array[i] = 0; for (int i = 0; i < 1000; ++i) array[i] = arrayhelper[i]; pthread_mutex_unlock(&lock); return 1; } void *read_array(){ while(1) { // 读操作前加锁 pthread_mutex_lock(&lock); if (array[10] == 0) printf("%d failed to lock!\n", array[10]); // 读操作结束解锁 pthread_mutex_unlock(&lock); // 可选:加短休眠避免线程空转占满CPU usleep(100); } } void *write_array(){ while(1) { sleep(1); change_array(array); } } int main (){ pthread_mutex_init(&lock, NULL); for (int i = 0; i < 1000; ++i) array[i] = i; pthread_create(&threads[0], NULL, *write_array, NULL); pthread_create(&threads[1], NULL, *read_array, NULL); pthread_create(&threads[2], NULL, *read_array, NULL); pthread_create(&threads[3], NULL, *read_array, NULL); pthread_create(&threads[4], NULL, *read_array, NULL); pthread_create(&threads[5], NULL, *read_array, NULL); pthread_create(&threads[6], NULL, *read_array, NULL); pthread_create(&threads[7], NULL, *read_array, NULL); pthread_create(&threads[8], NULL, *read_array, NULL); pthread_create(&threads[9], NULL, *read_array, NULL); pthread_join(threads[0], NULL); pthread_join(threads[1], NULL); pthread_join(threads[2], NULL); pthread_join(threads[3], NULL); pthread_join(threads[4], NULL); pthread_join(threads[5], NULL); pthread_join(threads[6], NULL); pthread_join(threads[7], NULL); pthread_join(threads[8], NULL); pthread_join(threads[9], NULL); pthread_mutex_destroy(&lock); pthread_exit(NULL); return 1; }
修正后读线程必须持有锁才能读取数组内容,写线程修改数组时持有锁,读线程会阻塞在锁申请步骤,等写线程修改完成释放锁后才能拿到锁读取,此时数组已经完成全部回填,array[10]值为10,不会触发打印逻辑,符合预期。
内容的提问来源于stack exchange,提问作者saeid keneshli
相关产品推荐
相关产品推荐

