多线程竞争与线程池学习代码threads/threads.c、threads/threads_pool.c多线程最容易迷惑人的地方是代码看起来是一行CPU 执行时可能是多步。count在 C 代码里只有一行但底层大致要经历读取、加一、写回三个步骤。如果两个线程同时读取到旧值 50各自加一后都写回 51最后结果就是 51而不是预期的 52。这就是临界区竞争。项目里为了比较不同同步方式写了互斥锁、自旋锁、原子操作和 CAS。CAS 的代码如下voidcas_inc(int*cas_count){while(1){intold*cas_count;intnew_valueold1;if(__sync_bool_compare_and_swap(cas_count,old,new_value)){return;}}}CAS 的思想是乐观的先读旧值计算新值提交时让 CPU 判断当前值是否仍等于旧值。如果没人改过就交换成功如果被其他线程改过就继续重试。它避免了阻塞但在竞争特别激烈时会反复失败CPU 时间会花在重试上。所以同步方案没有绝对最好只有适用场景临界区短可以考虑自旋或原子操作临界区长更适合互斥锁简单计数优先用原子操作复杂共享结构通常需要锁保护。线程池则解决另一个问题不能因为有很多任务就无限创建线程。项目里的线程池由任务队列、worker 队列、互斥锁和条件变量组成typedefstructnManager{structnWorker*worker_head;structnTask*task_head;pthread_mutex_tmutex;pthread_cond_tcond;}ThreadPool;添加任务时把任务插入队列并pthread_cond_signal()通知 workerworker 没任务时在条件变量上等待有任务时取出任务执行while(pool-task_headNULL){if(worker-terminate)break;pthread_cond_wait(pool-cond,pool-mutex);}我的理解是多线程编程要同时考虑正确性和资源管理。锁、CAS 解决的是共享数据正确性线程池解决的是线程数量和任务调度。只知道创建线程程序很容易在线程数量上失控只知道加锁又可能把并发性能锁没了。真正的并发设计是在安全、性能和复杂度之间找到平衡。学习链接: https://github.com/0voice