#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
// 定义互斥锁
pthread_mutex_t mutex;
// 定义条件变量
pthread_cond_t cond;
// 用于存储累加和
int sum = 0;
// 计算1到100的累加和的线程函数
void* sum_thread(void* arg) {
for (int i = 1; i <= 100; i++) {
sum += i;
}
// 锁住互斥锁
pthread_mutex_lock(&mutex);
// 发送条件变量信号
pthread_cond_signal(&cond);
// 解锁互斥锁
pthread_mutex_unlock(&mutex);
pthread_exit(NULL);
}
// 打印从A到Z字母的线程函数
void* print_thread(void* arg) {
// 锁住互斥锁
pthread_mutex_lock(&mutex);
// 等待条件变量信号,等待时会解锁互斥锁,被唤醒后重新加锁
pthread_cond_wait(&cond, &mutex);
for (char ch = 'A'; ch <= 'Z'; ch++) {
printf("%c ", ch);
}
printf("\n");
// 解锁互斥锁
pthread_mutex_unlock(&mutex);
pthread_exit(NULL);
}
int main() {
pthread_t tid1, tid2;
// 初始化互斥锁
pthread_mutex_init(&mutex, NULL);
// 初始化条件变量
pthread_cond_init(&cond, NULL);
// 创建计算累加和的线程
if (pthread_create(&tid1, NULL, sum_thread, NULL) != 0) {
perror("pthread_create");
return 1;
}
// 创建打印字母的线程
if (pthread_create(&tid2, NULL, print_thread, NULL) != 0) {
perror("pthread_create");
return 1;
}
// 等待两个线程结束
pthread_join(tid1, NULL);
pthread_join(tid2, NULL);
// 销毁互斥锁
pthread_mutex_destroy(&mutex);
// 销毁条件变量
pthread_cond_destroy(&cond);
printf("1到100的累加和为: %d\n", sum);
return 0;
}
互斥锁的作用原理
- 基本概念:互斥锁(Mutex,即Mutual Exclusion的缩写)是一种特殊的二元信号量,它的值只能是0或1。其主要作用是保证在同一时刻只有一个线程能够访问共享资源,防止多个线程同时访问共享资源而导致数据竞争和不一致的问题。
- 工作流程:
- 加锁:当一个线程调用
pthread_mutex_lock
函数尝试获取互斥锁时,如果互斥锁当前的值为1(表示未被锁定),则该函数会将互斥锁的值设为0(表示已被锁定),然后线程可以继续执行临界区(共享资源访问代码)的代码。如果互斥锁当前的值为0(已被其他线程锁定),则调用pthread_mutex_lock
的线程会被阻塞,直到互斥锁被解锁。
- 解锁:当线程完成对共享资源的访问后,调用
pthread_mutex_unlock
函数将互斥锁的值设为1(解锁),此时如果有其他线程正在等待获取该互斥锁,则系统会唤醒其中一个等待线程,让其获取互斥锁并进入临界区。在本代码中,通过互斥锁和条件变量结合使用,保证了打印字母的线程在累加和计算完成后才开始执行。计算累加和的线程在完成计算后,通过互斥锁保护条件变量的发送操作,打印线程在等待条件变量时,先获取互斥锁,等待过程中会释放互斥锁,被唤醒后重新获取互斥锁,从而确保线程同步。