我正在编写一个程序,它有一个写入线程和几个读取线程,可以写入/读取磁盘上的文件。我希望不会同时发生写/读。我发现许多使用pthread互斥锁来保护存储器阵列的例子,例如声明受保护的存储器阵列volatile。
volatile int array[NUMBER];
pthread_mutex_t locks[NUMBER];
pthread_mutex_lock(&locks[index]);
array[acct] -= SOME_NUMBER;
pthread_mutex_unlock(&locks[index]);
但是我找不到使用pthread来保护磁盘上文件的例子。
volatile FILE* array[NUMBER]; ??
有人能指出我正确的方向吗?我希望写/读线程不会同时访问磁盘上的文件。
编辑:我阅读了更多内容,根据此post,似乎多线程不适用于磁盘IO。
答案 0 :(得分:4)
根据说明,您的问题是保护磁盘上的文件,而不是代表文件的流描述符(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);
请注意,这可以保护文件不被同一进程中的多个线程访问,这不能保护它不被系统上的多个进程访问。
答案 1 :(得分:2)
这取决于你的意思是“不会同时访问磁盘上的文件”。既然你谈到pthreads,那就意味着你在POSIX系统上。 POSIX已经对多个进程和线程的文件访问提供了一定的保证。
如果使用原始系统调用read
和write
,则可以保证写入将是原子的。这意味着,如果同时发生read
和write
(意思是:您不知道哪个首先启动),则读取将看到写入文件的整个更改,或者没有看到(这里可能有一些例外的错误)。当然,多个线程读取和写入相同的文件描述符存在问题,因为读/写更新下一个读/写将发生的偏移。因此,如果某个其他线程可以触发搜索和写入之间的文件描述符,那么执行lseek
然后write
是不安全的。但是为此你有系统调用pread
和pwrite
来保证搜索+读/写将是原子的。
所以,只需进入问题描述的这一部分:
一个写入线程和一些读取线程,它们写入/读取磁盘上的文件。我希望不会同时发生写/读。
操作系统已经保证了这一点。我认为这个问题是“同时”是一个非常模糊的要求,因为几乎没有任何访问共享资源(如文件甚至内存)的东西同时发生。在考虑线程或任何并发时,您需要根据在其他事情之前/之后需要发生的事情来构建问题。