Write-Once, Read-Many Lock

折月煮酒 提交于 2019-12-10 11:58:52

问题


I know this topic has been pounded as I have read gillions of posts on SO as well as elsewhere about it, but I have yet to find a definitive answer, so my apologies if you are offended by this seeming redundancy.

I have a situation where there is a write-once, read-millions resource. The resource is extremely expensive to create and the contention on the write-lock could be very high as well. Furthermore, I cannot predict what processor this will be run on and so I do not know what the memory-model will be underneath. I am compiling 3 versions of the assembly built in .NET 3.5, .NET 4.0, and Mono 2.10.

Because of the high-contention for the resource, I need to make this as efficient as possible and would like to use a lock-free pattern, at least for the reads. I understand the double lock check pattern for creating the resource, but there has been disagreement over whether or not it works (on all processors) due to the access of _resource outside the memory barrier. Do I need to use volatile on the _resource field? Is a ReaderWriterLockSlim a better fit for this scenario? What other questions should I be asking?

if(_resource == null)
{
    lock(_locker)
    {
        if(_resource == null)
        {
            //create resource here...
        }      
    }
}

In addition, there will be a number of these:

if(_resource == null)
{
    return _resourceDefault;
}

return _resource.GetSomething();

回答1:


Decided to promote my comment to an answer.

On creating singleton's read, http://msdn.microsoft.com/en-us/library/ff650316.aspx . It cross links a paper that goes in depth explaining some of the problems related to double checked locking. To be completely safe the microsoft article does recommend the volatile.

A reader writer lock doesn't really buy you anything if all you really just want is to create a singleton (one time thing... no lock promotion or anything is necessary. You really just need to protect creation of the resource). Once the resource is created you won't be touching the lock at all.

I would design access to your singleton to always go through a static property/method so you can always do the double check.

About the resource default, I don't think I know enough about your situation to answer properly. Do you expect the primary resource to ever be null (except before it was created)? Depending on your use case, you might be able to use a Moniter.TryEnter which is nonblocking and returns a value letting you know if you received the lock. If you were not able to immediately get the lock to create the singleton, you could return your default.



来源:https://stackoverflow.com/questions/11503874/write-once-read-many-lock

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!