面临的问题
- 数据竞争:多个线程同时访问和操作文件缓冲区,可能导致数据竞争,使文件内容错乱。
- 缓冲区不一致:每个线程有自己的缓冲区,可能出现线程A写入缓冲区但未及时刷新到文件,线程B又写入,造成数据丢失或顺序错乱。
- 缓冲区刷新时机:不确定何时刷新缓冲区,可能导致部分数据滞留在缓冲区未写入文件。
解决方案
- 互斥锁(Mutex):使用互斥锁来保护对文件的操作。在每个线程写入文件前获取锁,写入完成后释放锁,保证同一时间只有一个线程能进行文件写入操作。
- 条件变量(Condition Variable):结合条件变量,当一个线程完成写入后,通知另一个线程可以开始写入,确保写入顺序。
设计方案
- 初始化部分:
- 创建一个互斥锁
pthread_mutex_t mutex
并初始化。
- 创建一个条件变量
pthread_cond_t cond
并初始化。
- 定义一个标志变量
int flag = 0
用于表示当前轮到哪个线程写入。
- 线程A的代码:
void* threadA(void* arg) {
pthread_mutex_lock(&mutex);
while(flag != 0) {
pthread_cond_wait(&cond, &mutex);
}
// 线程A写入自己缓冲区的数据到文件
// 假设文件指针为 FILE* file
fwrite(bufferA, sizeof(char), strlen(bufferA), file);
flag = 1;
pthread_cond_signal(&cond);
pthread_mutex_unlock(&mutex);
return NULL;
}
- 线程B的代码:
void* threadB(void* arg) {
pthread_mutex_lock(&mutex);
while(flag != 1) {
pthread_cond_wait(&cond, &mutex);
}
// 线程B写入自己缓冲区的数据到文件
fwrite(bufferB, sizeof(char), strlen(bufferB), file);
flag = 0;
pthread_cond_signal(&cond);
pthread_mutex_unlock(&mutex);
return NULL;
}
- 缓冲区相关操作:
- 在写入文件时,使用
fwrite
函数将缓冲区数据写入文件。
- 每次写入完成后,调用
fflush(file)
及时刷新文件缓冲区,确保数据真正写入文件,避免数据滞留在缓冲区。
- 在主线程中,在所有线程结束后,再次调用
fflush(file)
以及 fclose(file)
确保文件操作完成并关闭文件。
清理部分
- 在程序结束时,销毁互斥锁
pthread_mutex_destroy(&mutex)
。
- 销毁条件变量
pthread_cond_destroy(&cond)
。