同步与竞态条件
实现互斥锁和信号量,安全地管理共享资源
同步与竞态条件 是 CoddyKit 上的免费 C Academy 课时。 这是第 3 节课,共 3 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 C Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 C Academy 课程共包含 3 节课。
同步和竞态条件
当多个线程访问共享资源时,可能会发生竞态条件,从而导致不可预测的结果。
在本课中,您将学习:
- 竞态条件是什么,以及它们如何发生。
- 如何使用互斥锁防止竞态条件。
- 信号量如何帮助管理共享资源。

什么是竞态条件
当多个线程同时访问共享数据,导致不可预测的行为时,就会发生竞态条件。
示例:
- 两个线程尝试更新一个全局计数器。
- 由于相互干扰,最终值可能不正确。
示例:多线程中的竞态条件
此程序演示多个线程修改共享变量时产生的竞态条件。
#include <stdio.h>
#include <pthread.h>
int counter = 0;
void *incrementCounter(void *arg) {
for (int i = 0; i < 1000000; i++) {
counter++;
}
return NULL;
}
int main() {
pthread_t t1, t2;
pthread_create(&t1, NULL, incrementCounter, NULL);
pthread_create(&t2, NULL, incrementCounter, NULL);
pthread_join(t1, NULL);
pthread_join(t2, NULL);
printf("Final counter value: %d\n", counter);
return 0;
}使用互斥锁防止竞态条件
互斥锁(互相排斥)确保同一时间只有一个线程访问资源。
互斥锁函数:
pthread_mutex_init()- 初始化互斥锁。pthread_mutex_lock()- 锁定互斥锁。pthread_mutex_unlock()- 解锁互斥锁。pthread_mutex_destroy()- 销毁互斥锁。
示例:使用互斥锁防止竞态条件
此程序使用互斥锁控制对共享计数器的访问,从而解决竞态条件。
#include <stdio.h>
#include <pthread.h>
int counter = 0;
pthread_mutex_t lock;
void *incrementCounter(void *arg) {
for (int i = 0; i < 1000000; i++) {
pthread_mutex_lock(&lock);
counter++;
pthread_mutex_unlock(&lock);
}
return NULL;
}
int main() {
pthread_t t1, t2;
pthread_mutex_init(&lock, NULL);
pthread_create(&t1, NULL, incrementCounter, NULL);
pthread_create(&t2, NULL, incrementCounter, NULL);
pthread_join(t1, NULL);
pthread_join(t2, NULL);
pthread_mutex_destroy(&lock);
printf("Final counter value: %d\n", counter);
return 0;
}什么是信号量
信号量是一种用于控制资源访问的计数器。
主要函数:
sem_init()- 初始化信号量。sem_wait()- 减小信号量的值。sem_post()- 增大信号量的值。sem_destroy()- 销毁信号量。
示例:使用信号量进行同步
此程序使用信号量管理对共享资源的访问。
#include <stdio.h>
#include <pthread.h>
#include <semaphore.h>
sem_t sem;
void *task(void *arg) {
sem_wait(&sem);
printf("Thread %d is executing\n", *(int *)arg);
sem_post(&sem);
return NULL;
}
int main() {
pthread_t t1, t2;
int id1 = 1, id2 = 2;
sem_init(&sem, 0, 1);
pthread_create(&t1, NULL, task, &id1);
pthread_create(&t2, NULL, task, &id2);
pthread_join(t1, NULL);
pthread_join(t2, NULL);
sem_destroy(&sem);
return 0;
}线程同步最佳实践
要避免竞态条件:
- 使用互斥锁保护共享变量。
- 使用信号量管理资源。
- 在可能的情况下,尽量减少共享资源的使用。
总结
在本课中,您学习了:
- 竞态条件是什么,以及它们如何发生。
- 如何使用互斥锁防止竞态条件。
- 信号量如何帮助管理对共享资源的访问。
至此,C 语言中的多线程与并发部分就结束了!

用 AI 导师学习 C — 免费
在浏览器中编写并运行真实代码,获得全天候 AI 导师的即时帮助,并在网页或应用中继续学习。
- 课程
- 39
- 课程
- 144
常见问题解答
「同步与竞态条件」课时是免费的吗?
是的 — 「同步与竞态条件」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 C Academy 课程的其余内容,请升级到 CoddyKit PRO。 C Academy 课程共包含 3 节课。
「同步与竞态条件」这节课中我会学到什么?
实现互斥锁和信号量,安全地管理共享资源 你通过在浏览器中直接运行的动手代码来练习 C Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 C Academy 需要有经验吗?
无需任何先前经验。CoddyKit 上的 C Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 3 节课,共 3 节。
「同步与竞态条件」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 C Academy 课中编写并运行代码吗?
能。每节 C Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。