简体   繁体   English

如何在C中使用pthread防止同时读写磁盘上的文件?

[英]How to use pthread in C to prevent simultaneous read and write to a file on disk?

I am writing a program, which has 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. 我希望不会同时发生写入/读取。 I found many examples which uses pthread mutex lock to protect memory array during write / read, such as declaring the protected memory array volatile. 我发现了许多在写/读期间使用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]);

But I cannot find examples with using pthreads to protect files on disk. 但是我找不到使用pthread保护磁盘上文件的示例。

volatile FILE* array[NUMBER]; ??

Can someone point me to the right direction? 有人可以指出我正确的方向吗? I wish write / read threads will not access the files on disk simultaneously. 我希望写/读线程不会同时访问磁盘上的文件。

Edit: I read more, and according to this post , it seems that multithreading does not work with disk IO. 编辑:我读了更多,并且根据这篇文章 ,似乎多线程不适用于磁盘IO。

According to the description, your problem is about protecting the files on the disk, not the stream descriptors( FILE* ) that represents the files. 根据描述,您的问题与保护磁盘上的文件有关,而不是与代表文件的流描述符( FILE* )有关。 You can try to use pthread's rwlock to synchronize concurrent access between multiple threads: 您可以尝试使用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);

Note that this protect the file from accessed by multiple threads in the same process, this does not protect it from accessing by multiple processes on the system. 请注意,这可以防止文件被同一进程中的多个线程访问,这不能保护文件不被系统上的多个进程访问。

It depends on what you mean by "will not access the files on disk simultaneously". 这取决于您的意思是“将不会同时访问磁盘上的文件”。 Since you talk about pthreads, it means you're on a POSIX system. 由于您谈论的是pthreads,这意味着您正在使用POSIX系统。 POSIX already has certain guarantees about file access by multiple processes and threads. POSIX已经对多个进程和线程进行文件访问提供了某些保证。

If you use the raw system calls read and write you're for example guaranteed that writes will be atomic. 如果您使用原始的系统调用readwrite您例如保证写入将是原子。 This means that if a read and write happen simultaneously (meaning: you don't know which starts first), the read will either see the entire change to the file that the write did or none of it (there might be some exceptions here on errors). 这意味着,如果readwrite同时发生(意味着:您不知道哪个首先开始),则读取将看到写入所做的文件的全部更改,或者全部都看不到(此处可能会有一些例外)错误)。 Of course there are problems with reading and writing the same file descriptor by multiple threads since read/write updates the offset where the next read/write will happen. 当然,由于多个线程读取和写入同一文件描述符存在问题,因为读取/写入会更新将在下一次读取/写入发生的偏移量。 So doing an lseek and then write is unsafe if some other thread can touch the file descriptor between the seek and the write. 因此,如果其他一些线程可以在查找和写入之间触摸文件描述符,则先进行lseek然后write是不安全的。 But for that you have the system calls pread and pwrite that guarantee that the seek+read/write will be atomic. 但是为此,您需要系统调用preadpwrite ,以确保seek + read / write将是原子的。

So by just going on this part of your problem description: 因此,仅需进行问题描述的这一部分:

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. 我希望不会同时发生写入/读取。

this is already guaranteed by the operating system. 操作系统已经保证了这一点。 The problem I think is that "at the same time" is a very vague requirement because almost nothing that accesses a shared resource (like a file or even memory) happens at the same time. 我认为的问题是“同时”是一个非常模糊的要求,因为几乎没有任何事情同时发生在访问共享资源(例如文件或什至是内存)上。 When thinking about threads or just about any concurrency you need to frame the problem in terms of what needs to happen before/after some other thing. 在考虑线程或任何并发性时,您需要根据在发生其他事情之前/之后发生的事情来构造问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM