文章目录
并发下锁的机制详解
介绍了并发下的锁
一、互斥锁 (Mutex)
1.1 工作原理
互斥锁通过阻塞线程实现同步,当线程尝试获取已被占用的锁时,会进入睡眠状态,释放CPU资源,直到锁被释放后被唤醒。
1.2 适用场景
- 临界区操作较复杂(如文件IO操作)
- 锁持有时间较长
- 需要避免CPU空转的场景
1.3 代码示例改进
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
void *thread_callback(void *arg) {
int *pcount = (int *)arg;
for (int i = 0; i < 100000; i++) {
if (pthread_mutex_lock(&mutex) != 0) {
perror("mutex lock failed");
break;
}
(*pcount)++;
pthread_mutex_unlock(&mutex);
usleep(1);
}
return NULL;
}
二、自旋锁 (Spinlock)
2.1 工作原理
采用忙等待机制,线程不断尝试获取锁而不释放CPU,直到成功获取锁。
2.2 适用场景
- 临界区非常短(<几十条指令)
- 多核处理器环境
- 不能睡眠的上下文(如中断处理)
2.3 代码示例
pthread_spinlock_t spinlock;
int main() {
pthread_spin_init(&spinlock, PTHREAD_PROCESS_SHARED);
// 线程函数内使用:
pthread_spin_lock(&spinlock);
(*pcount)++;
pthread_spin_unlock(&spinlock);
}
三、原子操作与CAS
3.1 CAS原理深度解析
bool cas(int* ptr, int expect, int update) {
if (*ptr == expect) {
*ptr = update;
return true;
}
return false;
}
3.2 ABA问题解决方案
版本号方案:
struct atomic_with_version {
int value;
int version;
};
bool cas_version(struct atomic_with_version* ptr,
int expect_val, int expect_ver,
int new_val) {
if (ptr->value == expect_val && ptr->version == expect_ver) {
ptr->value = new_val;
ptr->version++;
return true;
}
return false;
}
四、锁机制对比表

五、线程池深度解析
5.1 核心组件
- 任务队列:使用环形缓冲区实现高效存取
- 工作者线程:采用pthread_cond_wait进行任务等待
- 动态扩容机制:
当任务数 > 核心线程数时创建新线程
空闲线程超过keepalive时间后自动回收
5.2 高级特性实现
typedef struct {
void (*function)(void *);
void *arg;
} threadpool_task_t;
struct threadpool {
pthread_mutex_t lock; // 全局锁
pthread_cond_t notify; // 条件变量
threadpool_task_t *queue; // 任务队列
int queue_size; // 队列容量
int head; // 队列头
int tail; // 队列尾
int count; // 当前任务数
pthread_t *threads; // 线程数组
int thread_count; // 活动线程数
int shutdown; // 关闭标志
};
六、性能优化策略
1. 锁粒度控制:
- 细粒度锁:对哈希表的不同桶使用独立锁
- 分段锁:将数据结构划分为多个段独立加锁
2. 无锁编程实践:
// 使用__atomic内置函数实现无锁队列
void enqueue(Node** head, int value) {
Node* newNode = create_node(value);
do {
newNode->next = *head;
} while (!__atomic_compare_exchange(head, &newNode->next, &newNode, false,
__ATOMIC_RELAXED, __ATOMIC_RELAXED));
}
3. 缓存友好设计:
- 避免false sharing:使用__attribute__((aligned(64)))对齐关键变量
- 热点数据隔离:将频繁访问的数据分配到不同缓存行
七、实战注意事项
1. 死锁预防:
- 严格按照固定顺序获取多个锁
- 使用pthread_mutex_trylock()设置超时
- 采用lock hierarchy验证加锁顺序
2. 性能监控:
# 使用perf分析锁竞争
perf record -e contention:contention_begin -a sleep 10
perf script
3. 调试技巧:
- 开启CLANG线程安全注解:
void do_work() __attribute__((acquire_capability(mutex))) {
pthread_mutex_lock(&mutex);
}
- 使用Helgrind检测数据竞争:
valgrind --tool=helgrind ./your_program
682

被折叠的 条评论
为什么被折叠?



