如何正确使用readwriterlock

发布于 2024-08-10 20:50:05 字数 906 浏览 5 评论 0 原文

您好,我需要在我的方法中使用 writerreaderlock。我想知道如何正确使用它。

我得到了一个 ObjectA 的字典

public class ObjectA
{
    public ReaderWriterLock RWL {get;set;}
    public ObjectB obj {get;set;}
    public ObjectA()
    {
        RWL = new ReaderWriterLock();
    }
}

public class ObjectB
{
    int TTL {get;set;}
    string Value {get;set;}
}

在我的方法中,我使用了一个 ObjectA 的字典,键是一个 Guid,所以假设当我调用 dict[guid] 时它总是返回一个 ObjectA 的实例(例如)

public foo()
{
    ObjecA objA = dict[guid];
    objA.RWL.AcquireReaderLock(500);
    if(objA.obj.TTL<=0)
    {
        objA.obj.RWL.AcquireWriterLock(1000);
        objA.obj.Value = DateTime.Now().ToString();
        objA.obj.RWL.ReleaseWriterLock();
    }else{
         int ttl = objA.obj.TTL;
         Interlocked.Decrement(ref ttl);
    }    
    objA.RWL.ReleaseReaderLock();
}

我真的不确定我在那里使用读取器和写入器,我需要如何使用读取器写入器锁并进行条件验证?

Hello i need to use writerreaderlock in my method. I want to know how use it correctly.

I got a dictionary of ObjectA

public class ObjectA
{
    public ReaderWriterLock RWL {get;set;}
    public ObjectB obj {get;set;}
    public ObjectA()
    {
        RWL = new ReaderWriterLock();
    }
}

public class ObjectB
{
    int TTL {get;set;}
    string Value {get;set;}
}

In my method I use a dictionary of ObjectA, the key is a Guid, so presume that when i call dict[guid] it always return an instance of my ObjectA (for the exemple)

public foo()
{
    ObjecA objA = dict[guid];
    objA.RWL.AcquireReaderLock(500);
    if(objA.obj.TTL<=0)
    {
        objA.obj.RWL.AcquireWriterLock(1000);
        objA.obj.Value = DateTime.Now().ToString();
        objA.obj.RWL.ReleaseWriterLock();
    }else{
         int ttl = objA.obj.TTL;
         Interlocked.Decrement(ref ttl);
    }    
    objA.RWL.ReleaseReaderLock();
}

I am really not sure of my using of reader and writer over there, how did i need to use reader writer lock, with a conditional validation ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

叹沉浮 2024-08-17 20:50:05

这段代码有很多问题,包括:

  • 您实际上并没有减少类实例中的 TTL——正如 Nikolai 指出的那样,您正在减少局部变量! Interlocked.Decrement(ref objA.obj.TTL) 是如何正确执行此操作的方法。
  • 您没有设置初始 TTL 值,因此它始终为零(除非其他一些代码正在设置它,这对于线程敏感类来说可能不明智,因为您通常希望所有与线程安全相关的代码都在同一个线程中)类以避免丢失跟踪谁在做什么)
  • 您应该使用 ReaderWriterLockSlim,现在优于旧版 ReaderWriterLock< /a> 类。请参阅后一个超链接了解原因。
  • 当获取写锁时,如果您已经有读锁,则需要升级锁——锁类上通常有一个单独的方法来实现这一点。同样,升级后释放锁需要一种方法来释放锁,而不是一种方法释放写锁,另一种方法释放之前的读锁。
  • 您需要处理无法获取锁的失败情况。
  • 您需要使用 使用try/finally 块以确保即使发生异常也能释放资源。

还可能值得考虑您是否真的需要使用读取器/写入器锁,而不是使用像 锁定{}语句。即使对于非常了解这些 API 和概念的开发人员来说,正确获取读取器/写入器锁定并避免死锁也是很困难的,即使如此,他们通常也只将其用途保留在对性能最关键的地方(每秒 1000 个以上)。换句话说,您可能最好从使用 lock{} 的更简单方法开始,只有在性能不可接受时才重新使用 ReaderWriterLockSlim

作为起点,我建议您在问题中添加更多信息:

  • 首先,包含您要执行的操作的高级描述,包括功能和性能的高级要求。这可以帮助我们推荐正确的解决方案并了解读取器/写入器锁定是否是正确的方法。
  • 尝试用伪代码或简单的英语准确地写出您希望代码的行为方式,包括您希望如何解决上述逻辑问题(例如,发生超时时该怎么办、如何设置 TTL 等)。 )
  • 修改您的代码示例以包括对我上面提到的部分/所有问题的修复。

我向您保证,如果您在问题中包含此附加信息,您将获得更好的答案,这可以帮助您解决任何剩余的代码问题。 :-)

There are many problems with this code, including:

  • you're not actually ever decrementing the TTL in your class instance-- as Nikolai points out, you're decrementing a local variable! Interlocked.Decrement(ref objA.obj.TTL) is how to do this properly.
  • you're not setting an initial TTL value, so it will always be zero (unless some other code is setting it, which is probably not wise for a threading-sensitive class where you generally want all thread-safety-related code in the same class to avoid losing track of who is doing what)
  • you should be using ReaderWriterLockSlim, which is now preferred to the older ReaderWriterLock class. See the latter hyperlink for why.
  • when acquiring a write lock, if you already have a read lock, you'll need to upgrade your lock-- there's usually a separate method on the lock class for that. Similarly, after you upgrade, releasing the lock requires one method to release the lock, not one to release the write lock and another to release the previous read lock.
  • you'll need to deal with the failure case where you are unable to acquire locks.
  • you'll want to wrap code in using or try/finally blocks to ensure that resources are freed even if an exception occurs.

It also may be worth considering whether you really, really need to use reader/writer locks, instead of using something simpler like the lock{} statement. Getting reader/writer locks right and avoiding deadlocks is hard even for developers who know these APIs and concepts really well, and even then they usually reserve their use for only the most performance-critical places (1000's+ per second). In other words, you may be better off starting out with a simpler approach using lock{}, and only falling back to using ReaderWriterLockSlim if performance is not acceptable.

As a starting point, I'd suggest you add some more info to your question:

  • first, include a high-level description of what you're trying to do, including high-level requirements for functionality and performance. this can help us recommend the right solution and to know if reader/writer lock is the right approach.
  • try to write out, in pseudo-code or just plain english, exactly how you want your code to behave, including how you want to address the logical issues above (e.g. what to do when a timeout happens, how is TTL set, etc.)
  • revise your code sample to include fixes for some/all of the problems I noted above

I guarantee you that if you include this addiitonal info in your question, you'll get better answers which can help you out with any any remaining code issues. :-)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文