标签: readerwriterlockslim

更快的TMultiReadExclusiveWriteSynchronizer?

那里有更快的那种TMultiReadExclusiveWriteSynchronizer吗?FastCode也许吧?

从Windows Vista开始,Microsoft添加了Slim Reader/Writer锁.它的性能比Delphi 好得多TMultiReadExclusiveWriteSynchronizer.不幸的是,它只存在于Windows Vista及更高版本中,这是很少有客户真正拥有的东西.

据推测,Slim Reader/Writer lock在本机中使用的概念可以在本机Delphi代码中重做 - 但有人做过吗?

我有一种情况,即获取和释放锁定TMultiReadExclusiveWriteSynchronizer(即使没有争用 - 单个线程),导致100%的开销(操作时间加倍).我可以在没有锁定的情况下运行,但是我的类不再是线程安全的.

有更快的TMultiReadExclusiveWriteSynchronizer吗?

注意:如果我使用TCriticalSectioni,只会遭受2%的性能损失(尽管已知关键部分在获取成功时很快,即它是单线程并且没有争用).CS的缺点是我失去了" 多个读者 "的能力.

测量

使用TMultiReadExclusiveWriteSynchronizer相当长的时间在内部BeginReadEndRead:

在此输入图像描述

然后移植代码以使用Window自己的SlimReaderWriter Lock(其中一些代码重写,因为它不支持递归锁定),并分析了resutls:

  • TMultiReadExclusiveWriteSynchronizer:每次迭代
    10,698 ns 10,697,772,613 ns,迭代1,000,000次

  • SRWLock:每次迭代
    8,802 ns,8,801,678,339 ns,迭代1,000,000次

  • Omni Reader-Writer lock:每次迭代8,941 ns,
    8,940,552,487 ns,迭代1,000,000次

使用SRWLocks(又名Omni的旋转锁)时,性能提高了17%.

现在,我不能永久地切换代码以使用Windows Vista SRWLocks,因为有些客户仍然在Windows XP上.

Slim锁只是小心使用InterlockedCompareExchange功能; 但比我能成功使用更加小心.我 …

delphi multithreading critical-section readerwriterlock readerwriterlockslim

22
推荐指数
1
解决办法
3842
查看次数

是否有一个ReaderWriterLockSlim等同于读者?

我已经使用了ReaderWriterLockSlim一段时间了,到目前为止它已经满足了我的需求.当我继续微调我的应用程序时,我发现这ReaderWriterLockSlim对我的用例来说有点不理想.

根据文献(和我的经验),它有利于作家而不是读者(即当读者和作家排队时,作家会得到偏好).但是,我需要一个有利于读者的同等学历.我理解这种成分的副作用(特别是作家饥饿问题).

是否有人可以指出的任何生产就绪的等价物?谢谢.

.net c# concurrency multithreading readerwriterlockslim

16
推荐指数
1
解决办法
1271
查看次数

C#ReaderWriterLockSlim避免递归的最佳实践

我有一个使用ReaderWriterLockSlim的类,它有一个read方法和一个write方法,它使用read方法来检索要修改的元素.一个简单的例子是:

class FooLocker
{
    ReaderWriterLockSlim locker = new ReaderWriterLockSlim();
    List<Foo> fooList = new List<Foo>();

    public void ChangeFoo(int index, string bar)
    {
        locker.EnterWriteLock();

        try
        {
            Foo foo = GetFoo(index);
            foo.Bar = bar;
        }
        finally
        {
            locker.ExitWriteLock();
        }
    }

    public Foo GetFoo(int index) 
    {
        locker.EnterReadLock(); //throws System.Threading.LockRecursionException

        try
        {
            return fooList[index];
        }
        finally
        {
            locker.ExitReadLock();
        }
    }

    //snipped code for adding instances etc.
}
Run Code Online (Sandbox Code Playgroud)

如上所述,此代码LockRecursionException在调用时抛出,ChangeFoo()因为在GetFoo()尝试输入读锁定时已经保持写锁定.

我已经检查了文档ReaderWriterLockSlim,我可以LockRecursionPolicy.SupportsRecursion用来允许上面的工作.但是,文档还建议不应将此用于任何新开发,并且只应在升级现有代码时使用.

鉴于此,在write方法可以使用只读方法检索需要修改的事物的情况下,实现相同结果的最佳实践是什么?

c# thread-safety readerwriterlockslim

15
推荐指数
1
解决办法
2万
查看次数

微软对ReaderWriterLockSlim.IsReadLockHeld/IsWriteLockHeld及其后果的评论

要同步对我的属性的访问,我使用ReaderWriterLockSlim类.我使用以下代码以线程安全的方式访问我的属性.

public class SomeClass
{
    public readonly ReaderWriterLockSlim SyncObj = new ReaderWriterLockSlim();  
    public string AProperty
    {
        get
        {
            if (SyncObj.IsReadLockHeld)
                return ComplexGetterMethod();
            SyncObj.EnterReadLock();
            try
            {
                return ComplexGetterMethod();
            }
            finally
            {
                SyncObj.ExitReadLock();
            }
        }
        set
        {
            if (SyncObj.IsWriteLockHeld)
                ComplexSetterMethod(value);
            else
            {
                SyncObj.EnterWriteLock();
                ComplexSetterMethod(value);
                SyncObj.ExitWriteLock();
            }
        }
    }

    // more properties here ...

    private string ComplexGetterMethod()
    {
        // This method is not thread-safe and reads
        // multiple values, calculates stuff, ect. 
    }

    private void ComplexSetterMethod(string newValue)    
    {
        // This method …
Run Code Online (Sandbox Code Playgroud)

c# readerwriterlockslim

14
推荐指数
1
解决办法
1951
查看次数

是否需要锁定对bool的访问权限,或者是否为Overkill

我有一个主要设计为POCO类的类,各种线程和任务可以读取其值,只有其他只偶尔更新这些值.这似乎是ReaderWriterLockSlim的理想场景.

问题是,在类中,如果属性需要是线程安全的,如果属性是bool,那是否过度杀伤?如果它是一个int会发生什么?约会时间?

public class MyClass
{
  private bool _theValue = false;
  private ReaderWriterLockSlim _theValueLock = new ReaderWriterLockSlim();

  public bool TheValue
  {
    get
    {
      bool returnVal = false;
      try
      {
        _theValueLock.EnterReadLock();
        returnVal = _theValue;
      }
      finally
      { _theValueLock.ExitReadLock(); }
      return returnVal;
    }
    set
    {
      try
      {
        _theValueLock.EnterWriteLock();
        _theValue = value;
      }
      finally
      { _theValueLock.ExitWriteLock(); }
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

所有这些代码都是矫枉过正的,而且简单......

public bool TheValue { get; set; }
Run Code Online (Sandbox Code Playgroud)

......会足够吗?因为Type是bool,安全吗?如果是的话,什么时候变得不安全?字节?诠释?约会时间?

编辑
我的基本架构是具有此类存储状态.也许有一个服务负责对这个类进行写操作.所有其他类都可以根据此状态数据读取和执行其逻辑.我会尽力确保所有数据都是一致的,但如下所述,我主要担心的是数据的原子性和危险性.

结论
感谢大家的回应,一切都很有价值.我主要担心的是写入/读取的原子性(即担心痉挛).对于.NET平台,如果有问题的变量是一个小于4个字节的内置值类型,则读取和写入是原子的(例如,short和int很好,long和double不是).

c# multithreading locking readerwriterlockslim

12
推荐指数
3
解决办法
6584
查看次数

是否有与ReaderWriterLockSlim相同的lock {}语句?

我喜欢C#中的快捷方式lock(myLock){ /* do stuff */}.是否有读/写锁的等价物?(特别是ReaderWriterLockSlim.)现在,我使用以下自定义方法,我认为它有效,但有点烦人,因为我必须将我的操作作为匿名函数传递,我宁愿使用标准锁定机制,如果可能的话.

    void bool DoWithWriteLock(ReaderWriterLockSlim RWLock, int TimeOut, Action Fn)
    {
        bool holdingLock = false;
        try
        {
            if (RWLock.TryEnterWriteLock(TimeOut))
            {
                holdingLock = true;
                Fn();
            }
        }
        finally
        {
            if (holdingLock)
            {
                RWLock.ExitWriteLock();
            }
        }
        return holdingLock;
    }
Run Code Online (Sandbox Code Playgroud)

.net c# locking readerwriterlockslim

9
推荐指数
1
解决办法
882
查看次数

如何在writer尝试输入写锁定时避免阻塞ReaderWriterLockSlim读取器

我正在ReaderWriterLockSlim用来保护一些操作.我想赞成读者而不是作家,这样当读者长时间持有锁并且作家试图获得写锁时,未来的读者也不会被作者的尝试所阻挡(如果是这样的话会发生这种情况.作家被封锁了lock.EnterWriteLock()).

为此,我虽然编写器可以TryEnterWriteLock在循环中使用短暂的超时,以便后续的读者仍然能够获得读锁定而编写者不能.然而,令我惊讶的是,我发现一个不成功的呼叫TryEnterWriteLock改变了锁的状态,无论如何阻止了未来的读者.概念证明代码:

System.Threading.ReaderWriterLockSlim myLock = new System.Threading.ReaderWriterLockSlim(System.Threading.LockRecursionPolicy.NoRecursion);

System.Threading.Thread t1 = new System.Threading.Thread(() =>
{
    Console.WriteLine("T1:{0}: entering read lock...", DateTime.Now);
    myLock.EnterReadLock();
    Console.WriteLine("T1:{0}: ...entered read lock.", DateTime.Now);

    System.Threading.Thread.Sleep(10000);
});

System.Threading.Thread t2 = new System.Threading.Thread(() =>
{
    System.Threading.Thread.Sleep(1000);

    while (true)
    {
        Console.WriteLine("T2:{0}: try-entering write lock...", DateTime.Now);
        bool result = myLock.TryEnterWriteLock(TimeSpan.FromMilliseconds(1500));
        Console.WriteLine("T2:{0}: ...try-entered write lock, result={1}.", DateTime.Now, result);

        if (result)
        {
            // Got it!
            break;
        }

        System.Threading.Thread.Yield();
    }

    System.Threading.Thread.Sleep(9000);
});

System.Threading.Thread t3 = new System.Threading.Thread(() => …
Run Code Online (Sandbox Code Playgroud)

.net multithreading readerwriterlockslim

9
推荐指数
1
解决办法
2517
查看次数

ReaderWriterLockSlim出错

我得到了这个异常
读取锁定被释放而没有被释放.
在System.Threading.ReaderWriterLockSlim.ExitReadLock()at .. GetBreed(String)

下面是访问锁的代码中唯一的位置.如您所见,没有递归.我无法理解如何发生此异常.

static readonly Dictionary<string, BreedOfDog> Breeds 
     = new Dictionary<string,BreedOfDog>();

static BreedOfDog GetBreed(string name)
{
        try
        {
            rwLock.EnterReadLock();
            BreedOfDog bd;
            if (Breeds.TryGetValue(name, out bd))
            {
                return bd;
            }
        }
        finally
        {
            rwLock.ExitReadLock();
        }

        try
        {
            rwLock.EnterWriteLock();
            BreedOfDog bd;
            //make sure it hasn't been added in the interim
            if (Breeds.TryGetValue(t, out bd)
            {
                return bd;
            }
            bd = new BreedOfDog(name); //expensive to fetch all the data needed to run  the constructor, hence the caching

            Breeds[name] = bd; …
Run Code Online (Sandbox Code Playgroud)

c# multithreading readerwriterlockslim

8
推荐指数
1
解决办法
1618
查看次数

使用ReaderWriterLock的真正缺点是什么?

我们有项目目标.NET 2.0 RTM(是的,它应该是.NET 2.0 RTM,我们有一些正统的客户端).而我只是想知道ReaderWriterLock的缺点是什么?为什么每个人都说"不要使用它,尝试使用其他类似lock声明" 这么糟糕?如果我们可以使用.NET 3.5,我肯定会使用ReaderWriterLockSlim,但ReaderWriterLock我对所有这些来自各地的警告都有点害怕.有人测量过表现还是其他什么?如果存在一些性能问题,我们可以在哪些有效负载下遇到它们?

我们在ReaderWriterLock主要目的方面有一个经典的情况,即多次读取和很少写入.使用lock语句会阻止所有读者.也许对我们来说这不是一个可怕的问题,但如果我可以使用,ReaderWriterLock我会更满意.国际海事组织介绍几台显示器确实是一个非常糟糕的主意.

.net c# multithreading readerwriterlock readerwriterlockslim

7
推荐指数
1
解决办法
2470
查看次数

使用ReaderWriterLockSlim.EnterXXX()的模式与随后的try-finally子句是否完全安全

MSDN文档和许多使用ReaderWriterLockSlim类的示例建议使用以下模式:

cacheLock.EnterWriteLock();
try
{
    //Do something
}
finally
{
    cacheLock.ExitWriteLock();
}
Run Code Online (Sandbox Code Playgroud)

但我很好奇它是否完全安全.获取锁之后是否可能发生某些异常,但是在try语句之前锁定被锁定状态?最明显的候选人是ThreadAbortException.我知道这种情况的可能性非常小,但后果极其糟糕 - 所以我认为值得考虑一下.我不相信编译器理解这种模式并阻止处理器在try语句之前中断线程.

如果理论上有可能这个代码不安全,有没有办法让它更安全?

.net c# multithreading readerwriterlockslim

7
推荐指数
2
解决办法
841
查看次数