全局计数器与并发线程:为何线程1结束时计数器值异常偏高?
线程计数异常问题分析与修正
问题原因分析
你的代码逻辑导致thread1打印的计数器值偏高,核心原因如下:
线程调度与结束顺序
你使用pthread_mutex_trylock尝试获取锁,锁被占用时线程会直接空转等待。实际系统调度中,先创建的thread1往往能获得更多初始执行机会,会先完成自身200万次计数循环(i达到MAX)。此时thread2仍在运行并继续递增计数器,因此thread1打印的是它结束瞬间的计数器值(约380-390万,即自身200万加上thread2已完成的180-190万);而thread2作为最后结束的线程,会打印最终的400万。未初始化共享变量
通过malloc分配的counter结构体未初始化,counter->value的初始值是内存随机垃圾值,可能导致计数结果出现不可预期的偏差。
实现的不合理之处
- 低效的锁使用:
pthread_mutex_trylock会导致线程空转浪费CPU,对于互斥访问场景,pthread_mutex_lock(阻塞式等待锁)才是更合理的选择。 - 类型匹配问题:
MAX是unsigned long类型,但i是uint32_t、counter->value是int,类型不统一存在潜在隐患;虽然400万未超出32位int范围,但建议使用uint32_t避免溢出风险。
修正后的代码
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <pthread.h> #include <stdint.h> #define MAX 2000000UL pthread_mutex_t lock; struct shared_data { uint32_t value; /* 使用无符号32位类型,避免溢出隐患 */ }; struct shared_data *counter; void* threadFunc(void * tid){ uint32_t i = 0; uint32_t thread_id = *(uint32_t*)tid; while(i < MAX){ pthread_mutex_lock(&lock); // 改用阻塞式锁,避免空转浪费CPU counter->value++; pthread_mutex_unlock(&lock); i++; } printf("I am thread %u. I counted %u times. Global counter = %u\n", thread_id, i, counter->value); return NULL; } int main() { counter = (struct shared_data *) malloc(sizeof(struct shared_data)); counter->value = 0; // 明确初始化计数器为0 printf("Initial Counter Value: %u\n", counter->value); pthread_t thread1; pthread_t thread2; uint32_t tid1 = 1, tid2 = 2; pthread_mutex_init(&lock, NULL); pthread_create(&thread1, NULL, threadFunc, &tid1); pthread_create(&thread2, NULL, threadFunc, &tid2); pthread_join(thread1,NULL); pthread_join(thread2,NULL); printf("Final Counter: %u\n", counter->value); // 释放资源,避免泄漏 pthread_mutex_destroy(&lock); free(counter); return 0; }
修正说明
- 初始化共享变量:将
counter->value初始化为0,消除随机初始值的影响。 - 优化锁逻辑:用
pthread_mutex_lock替代trylock,阻塞式等待锁避免CPU空转,同时保证共享变量的互斥访问更可靠。 - 统一变量类型:将
counter->value改为uint32_t,与MAX、i类型保持一致,避免类型转换隐患。 - 复用线程函数:合并两个线程函数,通过传递线程ID区分,减少代码冗余。
- 资源释放:添加锁销毁和内存释放操作,避免资源泄漏。
修正后,线程结束顺序仍可能随机,但先结束的线程打印的计数器值会在200万-400万之间波动,最终计数器值稳定为400万,符合预期。
内容的提问来源于stack exchange,提问作者Matthew
相关产品推荐
相关产品推荐

