如何在 C 中使用 pthread 来防止同时读取和写入磁盘上的文件?
How to use pthread in C to prevent simultaneous read and write to a file on disk?
我正在编写一个程序,它有一个写入线程和几个读取线程,write/read 到磁盘上的一个文件。我希望不会同时发生写入/读取。我发现了很多使用 pthread mutex lock 在写入/读取期间保护内存数组的示例,例如声明受保护的内存数组为 volatile。
volatile int array[NUMBER];
pthread_mutex_t locks[NUMBER];
pthread_mutex_lock(&locks[index]);
array[acct] -= SOME_NUMBER;
pthread_mutex_unlock(&locks[index]);
但我找不到使用 pthreads 保护磁盘文件的示例。
volatile FILE* array[NUMBER]; ??
有人能给我指出正确的方向吗?我希望写入/读取线程不会同时访问磁盘上的文件。
编辑:我读了更多,根据这个post,多线程似乎不适用于磁盘 IO。
根据描述,您的问题是关于保护磁盘上的文件,而不是代表文件的流描述符(FILE*
)。可以尝试使用pthread的rwlock来同步多线程间的并发访问:
FILE *fp = fopen(...);
pthread_rwlock_t rwlock = PTHREAD_RWLOCK_INITIALIZER;
// read thread:
char buf[BUFLEN];
pthread_rwlock_rdlock(&rwlock);
fread(buf, sizeof buf, 1, fp);
pthread_rwlock_unlock(&rwlock);
// write thread:
pthread_rwlock_wrlock(&rwlock);
fwrite(buf, sizeof buf, 1, fp);
pthread_rwlock_unlock(&rwlock);
请注意,这可以防止文件被同一进程中的多个线程访问,但这并不能防止它被系统上的多个进程访问。
这取决于你所说的 "will not access the files on disk simultaneously" 是什么意思。由于您谈论的是 pthreads,这意味着您使用的是 POSIX 系统。 POSIX 已经对多进程和线程的文件访问有了一定的保证。
如果您使用原始系统调用 read
和 write
,例如,您可以保证写入是原子的。这意味着如果 read
和 write
同时发生(意思是:您不知道哪个先开始),读取将看到写入所做的文件的整个更改或 none 的(这里可能有一些错误的例外)。当然,由于 read/write 更新下一个 read/write 将发生的偏移量,因此多个线程读写相同的文件描述符存在问题。因此,如果其他线程可以在查找和写入之间触及文件描述符,则执行 lseek
然后 write
是不安全的。但是为此你有系统调用 pread
和 pwrite
保证 seek+read/write 将是原子的。
所以只要继续你的问题描述的这一部分:
one write thread, and a few read threads, that write/read to a file on disk. I wish that no write / read will happen at the same time.
操作系统已经保证了这一点。我认为的问题是 "at the same time" 是一个非常模糊的要求,因为几乎没有什么访问共享资源(比如文件甚至内存)同时发生。在考虑线程或任何并发时,您需要根据需要发生的事情来构建问题 before/after 其他事情。
我正在编写一个程序,它有一个写入线程和几个读取线程,write/read 到磁盘上的一个文件。我希望不会同时发生写入/读取。我发现了很多使用 pthread mutex lock 在写入/读取期间保护内存数组的示例,例如声明受保护的内存数组为 volatile。
volatile int array[NUMBER];
pthread_mutex_t locks[NUMBER];
pthread_mutex_lock(&locks[index]);
array[acct] -= SOME_NUMBER;
pthread_mutex_unlock(&locks[index]);
但我找不到使用 pthreads 保护磁盘文件的示例。
volatile FILE* array[NUMBER]; ??
有人能给我指出正确的方向吗?我希望写入/读取线程不会同时访问磁盘上的文件。
编辑:我读了更多,根据这个post,多线程似乎不适用于磁盘 IO。
根据描述,您的问题是关于保护磁盘上的文件,而不是代表文件的流描述符(FILE*
)。可以尝试使用pthread的rwlock来同步多线程间的并发访问:
FILE *fp = fopen(...);
pthread_rwlock_t rwlock = PTHREAD_RWLOCK_INITIALIZER;
// read thread:
char buf[BUFLEN];
pthread_rwlock_rdlock(&rwlock);
fread(buf, sizeof buf, 1, fp);
pthread_rwlock_unlock(&rwlock);
// write thread:
pthread_rwlock_wrlock(&rwlock);
fwrite(buf, sizeof buf, 1, fp);
pthread_rwlock_unlock(&rwlock);
请注意,这可以防止文件被同一进程中的多个线程访问,但这并不能防止它被系统上的多个进程访问。
这取决于你所说的 "will not access the files on disk simultaneously" 是什么意思。由于您谈论的是 pthreads,这意味着您使用的是 POSIX 系统。 POSIX 已经对多进程和线程的文件访问有了一定的保证。
如果您使用原始系统调用 read
和 write
,例如,您可以保证写入是原子的。这意味着如果 read
和 write
同时发生(意思是:您不知道哪个先开始),读取将看到写入所做的文件的整个更改或 none 的(这里可能有一些错误的例外)。当然,由于 read/write 更新下一个 read/write 将发生的偏移量,因此多个线程读写相同的文件描述符存在问题。因此,如果其他线程可以在查找和写入之间触及文件描述符,则执行 lseek
然后 write
是不安全的。但是为此你有系统调用 pread
和 pwrite
保证 seek+read/write 将是原子的。
所以只要继续你的问题描述的这一部分:
one write thread, and a few read threads, that write/read to a file on disk. I wish that no write / read will happen at the same time.
操作系统已经保证了这一点。我认为的问题是 "at the same time" 是一个非常模糊的要求,因为几乎没有什么访问共享资源(比如文件甚至内存)同时发生。在考虑线程或任何并发时,您需要根据需要发生的事情来构建问题 before/after 其他事情。