|
dev
newsgroups
|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
Question about ReaderWriterLockI've got a question about ReaderWriterLock: Let's say I want to write a function that will update an object under write lock both if the calling thread has a reader lock or not. That Is, I want a function Write() that will work properly in both these cases: static int i=0; static public ReaderWriterLock locker=new ReaderWriterLock(); static public void Main() { Write(0); // write to i outside reader lock. locker.AquireReaderLock(); Write(i*2); // write to i unside reader lock. locker.ReleaseReaderLock(); } The only way I could think to write the function is something like this: static public void Write(int val) { System.Threading.LockCookie cookie=new System.Threading.LockCookie(); bool upgraded=false; if (locker.IsReaderLockHeld) { cookie= locker.UpgradeToWriterLock(5000); upgraded=true; } else { locker.AcquireWriterLock(5000); } try { i=val; } finally { if (upgraded) { locker.DowngradeFromWriterLock(ref cookie); } else { locker.ReleaseWriterLock(); } } } This seems to do the work, but the code is a bit... complicated.. Why does locker.AquireWriteLock() inside a reader lock block? This does not make much sense to me... Thanks, Nadav Hi Nadav,
Based on my understanding, you want to know about why ReaderWriterLock does not allow AcquireWriteLock to be called when the same thread has already acquired the reader lock. If I have misunderstood you, please feel free to tell me, thanks. Yes, your code logic is the correct programming style regarding ReaderWriterLock class. This will eliminate the potential deadlock. I think this requirement is by the design of the semantic. In "ReaderWriterLock Class" description, you can see that "A thread can hold a reader lock or a writer lock, but not both at the same time". So the ReaderWriterLock class design semantic does not allow a thread to acquire both reader lock and writer lock. Under this the design principle, if ReaderWriterLock allows you to acquire the writer clock while it is holding reader lock now, then this thread has the reader/writer lock at the same time, which will violate the semantic above. Ok, let's take another pratical example: We have 3 methods: BeginUpdateRead, EndUpdateRead, UpdateWrite. "BeginUpdateRead" will acquire the reader lock and start read the protected resource while "EndUpdateRead" will finish the remind read operations to the protected resource and release the reader lock. "UpdateWrite" will acquire the writer lock and modify the protected resource and release the writer. Now, in the single thread, we are calling the 3 methods: BeginUpdateRead UpdateWrite EndUpdateRead Note: we are using ReaderWriterLock to protect the shared resource, it means that we want to keep the modification to the shared resource as an atomic operation. "BeginUpdateRead" partially reads state #1 of the shared resource. Then if UpdateWrite succeeded with getting the writer lock, it will update the shared resource to state #2, then EndUpdateRead will finally read the remind state #2 of shared resource. So the reader will get the data mixed with state #1 and #2, which will violate the usage of ReaderWriterLock. So the ReaderWriterLock does not allow a thread to acquire the reader and writer lock at the same time. Hope it helps! Best regards, Jeffrey Tan Microsoft Online Community Support ================================================== Get notification to my posts through email? Please refer to http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif ications. Note: The MSDN Managed Newsgroup support offering is for non-urgent issues where an initial response from the community or a Microsoft Support Engineer within 1 business day is acceptable. Please note that each follow up response may take approximately 2 business days as the support professional working with you may need further investigation to reach the most efficient resolution. The offering is not appropriate for situations that require urgent, real-time or phone-based interactions or complex project analysis and dump analysis issues. Issues of this nature are best handled working with a dedicated Microsoft Support Engineer by contacting Microsoft Customer Support Services (CSS) at http://msdn.microsoft.com/subscriptions/support/default.aspx. ================================================== This posting is provided "AS IS" with no warranties, and confers no rights. Hi Jeffrey,
> I think this requirement is by the design of the semantic. In First of all, if this is a design decision, I think it would be better for > "ReaderWriterLock Class" description, you can see that "A thread can hold a > reader lock or a writer lock, but not both at the same time". So the > ReaderWriterLock class design semantic does not allow a thread to acquire > both reader lock and writer lock. Under this the design principle, if > ReaderWriterLock allows you to acquire the writer clock while it is holding > reader lock now, then this thread has the reader/writer lock at the same > time, which will violate the semantic above. ReaderWriterLock to throw an exception if trying to aquire Writer Lock when Reader lock is held by the same thread instead of deadlocking the application. > BeginUpdateRead BeginUpdateRead/EndUpdateRead sounds like Async operation that whould > UpdateWrite > EndUpdateRead execute on another thread (unless I'm very confused) so why would you lock the ReaderWriterLock on the original thread? And even if you do lock on the original thread, you can still use UpgradeToWriterLock to get a Writer Lock, so the problem still exists. Nadav Hi Nadav,
Thanks for your feedback. #1, yes, your suggestion of throwing exception makes sense. However, the current .Net implementation does not take the exception approach of notifying the developer yet. I will help to forward your suggestion. You may also submit this suggestion in the product feedback center below to increase the priority: https://connect.microsoft.com/content/content.aspx?ContentID=2220&wa=wsignin 1.0&siteid=-2 #2, sorry, I think there is some confusion in the naming of the methods. The BeginUpdateRead/EndUpdateRead in my sample are not the asychronous operations. They are 2 steps normal methods that read the protected share resource. "BeginUpdateRead" acquires the lock and reads first part of the shared resource, while the "UpdateWrite" is called to acquire the writer lock and modify the shared resource. Finally, "EndUpdateRead" reads the other part of the shared resource to finish the reading logic. In this process, the read operation will read the whole shared resource with one part with the old data and the other party with the modified data. So this will break the atom read logic. The reason I provide this example is that: in the scenario of acquiring a writer lock while holding the reader lock, it means that you still want to read the shared resource sometime after the writer lock(or, you may just release the reader lock and then acquire the writer lock). So there will be some additional read operation over the shared resource(EndUpdateRead). Hope this is clear to you now. Thanks. Best regards, Jeffrey Tan Microsoft Online Community Support ================================================== Get notification to my posts through email? Please refer to http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif ications. Note: The MSDN Managed Newsgroup support offering is for non-urgent issues where an initial response from the community or a Microsoft Support Engineer within 1 business day is acceptable. Please note that each follow up response may take approximately 2 business days as the support professional working with you may need further investigation to reach the most efficient resolution. The offering is not appropriate for situations that require urgent, real-time or phone-based interactions or complex project analysis and dump analysis issues. Issues of this nature are best handled working with a dedicated Microsoft Support Engineer by contacting Microsoft Customer Support Services (CSS) at http://msdn.microsoft.com/subscriptions/support/default.aspx. ================================================== This posting is provided "AS IS" with no warranties, and confers no rights. Hi Jeffrey,
Show quote > #2, sorry, I think there is some confusion in the naming of the methods. So the Same code, on the same thread, calls a function that aquired a read > The BeginUpdateRead/EndUpdateRead in my sample are not the asychronous > operations. They are 2 steps normal methods that read the protected share > resource. "BeginUpdateRead" acquires the lock and reads first part of the > shared resource, while the "UpdateWrite" is called to acquire the writer > lock and modify the shared resource. Finally, "EndUpdateRead" reads the > other part of the shared resource to finish the reading logic. In this > process, the read operation will read the whole shared resource with one > part with the old data and the other party with the modified data. So this > will break the atom read logic. > > The reason I provide this example is that: in the scenario of acquiring a > writer lock while holding the reader lock, it means that you still want to > read the shared resource sometime after the writer lock(or, you may just > release the reader lock and then acquire the writer lock). So there will be > some additional read operation over the shared resource(EndUpdateRead). lock, Then calls a function that aquires a write lock and does some changes, and attempts to continue reading from the object and reads inconsistant data? This has nothing to do with locks or threads! Locks are supposed to prevent OTHER threads from modifing your data. Nadav |
|||||||||||||||||||||||