简体   繁体   中英

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.

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.

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.

According to the description, your problem is about protecting the files on the disk, not the stream descriptors( FILE* ) that represents the files. You can try to use pthread's rwlock to synchronize concurrent access between multiple threads:

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. POSIX already has certain guarantees about file access by multiple processes and threads.

If you use the raw system calls read and write you're for example guaranteed that writes will be atomic. 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). 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. But for that you have the system calls pread and pwrite that guarantee that the seek+read/write will be atomic.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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