【问题标题】:How to use pthread in C to prevent simultaneous read and write to a file on disk?如何在 C 中使用 pthread 来防止同时读取和写入磁盘上的文件?
【发布时间】:2016-08-29 08:52:42
【问题描述】:

我正在编写一个程序,它有一个写入线程和几个读取线程,用于写入/读取磁盘上的文件。我希望不会同时发生写/读。我发现了许多在写/读期间使用 pthread 互斥锁来保护内存阵列的示例,例如声明受保护的内存阵列易失性。

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。

【问题讨论】:

  • volatile 部分与不同时访问无关。
  • 正如已经在 SO 上无休止地争论的那样,volatile 不会使读/写成为原子操作,也不能用于重入目的。但是,最好将与回调共享的所有变量声明为 volatile,以防止错误的编译器对代码进行不正确的优化,这些编译器没有意识到回调中的代码可以随时执行。在某些情况下,volatile 还可以充当内存屏障。

标签: c multithreading file pthreads mutex


【解决方案1】:

根据描述,您的问题是关于保护磁盘上的文件,而不是代表文件的流描述符(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);

请注意,这可以防止文件被同一进程中的多个线程访问,但这并不能防止文件被系统上的多个进程访问。

【讨论】:

  • 谢谢!看了更多的网上资源,好像多线程不支持磁盘IO。
  • @Pippi 您需要考虑这样一个事实,即文件是系统上每个人都可以看到的资源,而不仅仅是您的进程。因此,它将在您的进程是该文件的唯一用户的假设下工作。
  • 我同意。感谢您的建议!
【解决方案2】:

这取决于“不会同时访问磁盘上的文件”的含义。由于您谈论 pthreads,这意味着您在 POSIX 系统上。 POSIX 对于多进程和多线程的文件访问已经有了一定的保证。

如果您使用原始系统调用readwrite,例如可以保证写入是原子的。这意味着如果 readwrite 同时发生(意思是:你不知道哪个先开始),读取将看到写入所做的文件的全部更改或没有(可能有这里有一些关于错误的例外情况)。当然,多个线程读取和写入相同的文件描述符存在问题,因为读取/写入会更新下一次读取/写入发生的偏移量。因此,如果其他线程可以在查找和写入之间接触文件描述符,则执行lseek 然后write 是不安全的。但为此,您有系统调用 preadpwrite 保证查找+读/写将是原子的。

因此,只需继续您的问题描述的这一部分:

一个写入线程和几个读取线程,用于写入/读取磁盘上的文件。我希望不会同时发生写入/读取。

操作系统已经保证了这一点。我认为的问题是“同时”是一个非常模糊的要求,因为访问共享资源(如文件甚至内存)几乎没有同时发生。在考虑线程或任何并发时,您需要根据在其他事情之前/之后需要发生的事情来界定问题。

【讨论】:

猜你喜欢
  • 2019-11-22
  • 2011-04-05
  • 1970-01-01
  • 2018-02-25
  • 2010-10-10
  • 1970-01-01
  • 2015-12-02
  • 2019-11-13
  • 1970-01-01
相关资源
最近更新 更多