可能出现的问题
- 数据竞争:多个线程同时读写文件,可能导致数据不一致。例如,一个线程正在写入数据时,另一个线程开始读取,可能读到部分写入的数据,造成数据错误。
- 文件指针混乱:每个线程独立操作文件指针,可能使文件指针的位置错乱,导致读写位置不正确。
避免问题的机制
- 文件锁:
- 建议使用
fcntl
函数:在POSIX系统中,fcntl
函数可以用于设置文件锁。通过设置不同类型的锁(如读锁、写锁),可以控制多个线程对文件的访问。
- 示例代码:
#include <stdio.h>
#include <fcntl.h>
#include <pthread.h>
#include <unistd.h>
#define FILE_NAME "test.txt"
// 写线程函数
void* write_thread(void* arg) {
int fd = open(FILE_NAME, O_WRONLY | O_CREAT, 0666);
struct flock lock;
lock.l_type = F_WRLCK;
lock.l_whence = SEEK_SET;
lock.l_start = 0;
lock.l_len = 0;
// 获取写锁
fcntl(fd, F_SETLKW, &lock);
const char* data = "Hello, from write thread!";
write(fd, data, strlen(data));
// 释放写锁
lock.l_type = F_UNLCK;
fcntl(fd, F_SETLK, &lock);
close(fd);
return NULL;
}
// 读线程函数
void* read_thread(void* arg) {
int fd = open(FILE_NAME, O_RDONLY);
struct flock lock;
lock.l_type = F_RDLCK;
lock.l_whence = SEEK_SET;
lock.l_start = 0;
lock.l_len = 0;
// 获取读锁
fcntl(fd, F_SETLKW, &lock);
char buffer[100];
ssize_t bytes_read = read(fd, buffer, sizeof(buffer) - 1);
buffer[bytes_read] = '\0';
printf("Read data: %s\n", buffer);
// 释放读锁
lock.l_type = F_UNLCK;
fcntl(fd, F_SETLK, &lock);
close(fd);
return NULL;
}
int main() {
pthread_t write_tid, read_tid;
// 创建写线程
pthread_create(&write_tid, NULL, write_thread, NULL);
// 创建读线程
pthread_create(&read_tid, NULL, read_thread, NULL);
// 等待写线程结束
pthread_join(write_tid, NULL);
// 等待读线程结束
pthread_join(read_tid, NULL);
return 0;
}
- 线程同步:
- 使用互斥锁:在C语言中,可以使用POSIX线程库的互斥锁(
pthread_mutex_t
)。在进行文件读写操作前,先获取互斥锁,操作完成后释放互斥锁,这样可以保证同一时间只有一个线程能访问文件。
- 示例代码:
#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <string.h>
#define FILE_NAME "test.txt"
pthread_mutex_t mutex;
// 写线程函数
void* write_thread(void* arg) {
FILE* file = fopen(FILE_NAME, "w");
pthread_mutex_lock(&mutex);
const char* data = "Hello, from write thread!";
fwrite(data, strlen(data), 1, file);
fclose(file);
pthread_mutex_unlock(&mutex);
return NULL;
}
// 读线程函数
void* read_thread(void* arg) {
FILE* file = fopen(FILE_NAME, "r");
pthread_mutex_lock(&mutex);
char buffer[100];
fread(buffer, 1, sizeof(buffer) - 1, file);
buffer[feof(file)? strlen(buffer) : sizeof(buffer) - 1] = '\0';
printf("Read data: %s\n", buffer);
fclose(file);
pthread_mutex_unlock(&mutex);
return NULL;
}
int main() {
pthread_t write_tid, read_tid;
pthread_mutex_init(&mutex, NULL);
// 创建写线程
pthread_create(&write_tid, NULL, write_thread, NULL);
// 创建读线程
pthread_create(&read_tid, NULL, read_thread, NULL);
// 等待写线程结束
pthread_join(write_tid, NULL);
// 等待读线程结束
pthread_join(read_tid, NULL);
pthread_mutex_destroy(&mutex);
return 0;
}