9

how to write to a text file that can be accessed by multiple sources (possibly in a concurrent way) ensuring that no write operation gets lost?

Like, if two different processes are writing in the same moment to the file, this can lead to problems. The simples solution (not very fast and not very elegant) would be locking the file while beginning the process (create a .lock file or similar) and release it (delete the lock) while the writing is done.

When beginning to write, i would check if the .lock file exists and delay the writing till the file is released.

What is the recommended pattern to follow for this kind of situation?

Thanks

EDIT I mean processes, like different programs from different clients, different users and so on, not threads within the same program

pistacchio
  • 56,889
  • 107
  • 278
  • 420
  • You mean two different processes or threads? Cause if you want to have safe access to one file for few processes, there's not much you can do without using some Mutex, or other inter process locking mechanism. – Marcin Deptuła Jul 21 '09 at 16:25

6 Answers6

2

Consider using a simple database. You will get all this built-in safety relatively easy.

DanDan
  • 10,462
  • 8
  • 53
  • 69
2

The fastest way of synchronizing access between processes is to use Mutexes / Semaphores. This thread answers how to use them, to simulate read-writer lock pattern: Is there a global named reader/writer lock?

Community
  • 1
  • 1
Marcin Deptuła
  • 11,789
  • 2
  • 33
  • 41
  • There's a way to use a named Mutex that can be referenced from multiple processes. If all file access is from within a single process (but multiple threads), then they can all point to the same mutex to acquire the lock. – Kieveli Jul 21 '09 at 17:19
  • Kieveli - The author meant different processes, therefore - Mutexes / Semaphoers are the most obvious choices, and that's why I wrote about them, if we wold be talking about threads, both mutexes and simpler constructs like ReadWriteLock's would work. – Marcin Deptuła Jul 21 '09 at 17:29
1

I suggest using the ReaderWriterLock. It's designed for multiple readers but ensures only a single writer can writer data at any one time MSDN.

Ian
  • 33,605
  • 26
  • 118
  • 198
  • 3
    Don't use ReaderWriterLock, it has poor performance. Use ReaderWriterLockSlim or one of Jeffrey Richter's locks in the Wintellect PowerThreading library. – Matt Howells Jul 21 '09 at 16:31
  • 2
    Don't use neither ;). ReadWriter locks, Monitors (locks) etc. are not capable of inter process locks, which is what author meant I think (Like, if two different processes are writing in the same moment to the file)? – Marcin Deptuła Jul 21 '09 at 16:35
  • 1
    Don't use interprocess locking. Switch to an OS that only runs one process at a time. – Kieveli Jul 21 '09 at 17:18
  • Yeah, let's all start using MS-DOS – Marcin Deptuła Jul 21 '09 at 17:51
  • Ravadre, indeed they don't work across processes, however this answer was in well before the edit. I'll leave it here though in case anyone else stumbles across it looking for same process solutions. – Ian Jul 22 '09 at 07:44
1

I would look at something like the Command Pattern for doing this. Concurrent writing would be a nightmare for data integrity.

Essentially you use this pattern to queue your write commands so that they are done in order of request.

You should also use the ReaderWriterLock to ensure that you can read from the file while writing occurs. This would be a second line of defense behind the command pattern so that only one thread could write to the file at a given time.

joshlrogers
  • 1,136
  • 1
  • 11
  • 20
  • +1 for recommending using a queue, but I almost dinged you for the RW-lock comment afterwards. The Queue manages it's own locks... what else are you locking on? – Chris Arguin Jul 21 '09 at 17:09
  • I meant it more for a second line of defense. Which in hind sight I think there is a better way to do it than using the RWL, but I would hate to have him prematurely optimize despite the performance downfalls of RWL. However I am starting to wonder if he meant multiple different processes/apps accessing and writing to a file, and if so then both of these would be worthless. – joshlrogers Jul 21 '09 at 17:27
0

You can try lock too. It's easy - "lock ensures that one thread does not enter a critical section while another thread is in the critical section of code. If another thread attempts to enter a locked code, it will wait (block) until the object is released."

http://msdn.microsoft.com/en-us/library/c5kehkcz%28VS.71%29.aspx

Broken Link
  • 2,396
  • 10
  • 30
  • 47
  • Actually, using monitor (lock) is cheaper then ReaderWriterLockSlim.EnterWriteLock + ExitLock. It's great to use rw lock, when you have few readers and writers, but in this case, you rather won't read from file, as it's just a log file, you will mostly write to it, so you will need to use WriteLocks only anyways -> therefore, you won't be able to access concurrently to the resource -> therefore, you can use regular lock. Not mentioning, that both won't work for inter process sync. – Marcin Deptuła Jul 21 '09 at 16:47
0

I would also recommend you look for examples of having multiple readers and only 1 writer in a critical section heres a short paper with a good solution http://arxiv.org/PS_cache/cs/pdf/0303/0303005v1.pdf

Alternatively you could look at creating copies of the file each time it is requested and when it comes time to write any changes to the file you merge with the original file.

Michael Behan
  • 3,433
  • 2
  • 28
  • 38