SyncLock on Write? Read? Or both?
Asked Answered
L

2

6

Suppose I have a byte array, Private Data as Byte(). This array is private within a class. The class provides public functions for reading and writing to Data.

This class can be accessed by multiple threads, so I want to avoid a situation where reading from it and writing from it don't happen at the same time.

For now, I am using SyncLock to avoid issues. Can I put SyncLock Data in just the write functions, or does it need to be in the read functions? Or, both?

I don't have a specific code example in mind. I am just curious if there is any benefit to locking for both read and write functions if the writing functions' SyncLock will make writing have exclusive access to it in the first place.

Lala answered 7/1, 2011 at 1:16 Comment(0)
L
4

The main reason you would want to lock on reading a byte array is to avoid a "phantom read" or other non-repeatable read -- if a writer is partway through updating the array, a reader may see some old values and some new values, or an old value and then the new value if it reads it again.

For example, if you have an array containing [1, 2, 3, 4, 5, 6], and a writer thread that takes a SyncLock and loops over the array adding 1 to each element, a reader that does not SyncLock may see weirdness like [2, 3, 4, 4, 5, 6] -- only threads that actually take the SyncLock will receive any safety.

Lederer answered 7/1, 2011 at 1:20 Comment(5)
Yes, that is what I would like to avoid. But, if I am using SyncLock when writing to the byte array, I shouldn't have this problem, should I?Lala
Only the threads that participate in locking will be protected -- a thread that doesn't lock will be able to see half-updated state.Lederer
Yes you will. If you only lock on the write operation and not on read you may very well be reading invalid data. That is what this post is saying.Crosspollinate
Thanks for the edit, I see what you mean. So what is SyncLock actually locking then? I assumed it protected the object specified from being accessed by any other thread. Is that not the case?Lala
@Brad: It prevents two threads from entering any SyncLock's section which are locking on the same object. However, it doesn't prevent other objects from seeing that data. That must be protected in some other way.Conchoidal
C
5

Instead of using a SyncLock, you should consider using a ReaderWriterLockSlim (or ReaderWriterLock if you're not in .NET 4).

It is intended to allow a single writer, but multiple readers. This is typically ideal for a situation like the one you're describing.

Otherwise, you can use SyncLock, but you'll need to lock on both read and write operations. Without the lock on both, it's possible for your reader to read data while the writer is still writing - which will cause you to read half-set data.

Conchoidal answered 7/1, 2011 at 1:25 Comment(0)
L
4

The main reason you would want to lock on reading a byte array is to avoid a "phantom read" or other non-repeatable read -- if a writer is partway through updating the array, a reader may see some old values and some new values, or an old value and then the new value if it reads it again.

For example, if you have an array containing [1, 2, 3, 4, 5, 6], and a writer thread that takes a SyncLock and loops over the array adding 1 to each element, a reader that does not SyncLock may see weirdness like [2, 3, 4, 4, 5, 6] -- only threads that actually take the SyncLock will receive any safety.

Lederer answered 7/1, 2011 at 1:20 Comment(5)
Yes, that is what I would like to avoid. But, if I am using SyncLock when writing to the byte array, I shouldn't have this problem, should I?Lala
Only the threads that participate in locking will be protected -- a thread that doesn't lock will be able to see half-updated state.Lederer
Yes you will. If you only lock on the write operation and not on read you may very well be reading invalid data. That is what this post is saying.Crosspollinate
Thanks for the edit, I see what you mean. So what is SyncLock actually locking then? I assumed it protected the object specified from being accessed by any other thread. Is that not the case?Lala
@Brad: It prevents two threads from entering any SyncLock's section which are locking on the same object. However, it doesn't prevent other objects from seeing that data. That must be protected in some other way.Conchoidal

© 2022 - 2024 — McMap. All rights reserved.