螺纹锁紧佣工的安全使用(关于内存屏障) [英] Thread safe usage of lock helpers (concerning memory barriers)

查看:115
本文介绍了螺纹锁紧佣工的安全使用(关于内存屏障)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

通过锁定佣工我指的是与锁可以通过使用语句来实现一次性的对象。例如,考虑的的SyncLock 类的典型用法。 HTML相对=nofollow>乔恩斯基特的MiscUtil

By lock helpers I am referring to disposable objects with which locking can be implemented via using statements. For example, consider a typical usage of the SyncLock class from Jon Skeet's MiscUtil:

public class Example
{
    private readonly SyncLock _padlock;

    public Example()
    {
        _padlock = new SyncLock();
    }

    public void ConcurrentMethod()
    {
        using (_padlock.Lock())
        {
            // Now own the padlock - do concurrent stuff
        }
    }
}

现在,考虑以下用法:

var example = new Example();
new Thread(example.ConcurrentMethod).Start();



我的问题是这样的 - 因为例如是在一个线程中创建和 ConcurrentMethod 被称为另一个,不能 ConcurrentMethod 的主题是无视 _padock 的构造函数(由于线程缓存/读写重新排序),因此抛出一个的NullReferenceException (在<分配code> _padLock 本身)?

My question is this - since example is created on one thread and ConcurrentMethod is called on another, couldn't ConcurrentMethod's thread be oblivious to _padock's assignment in the constructor (due to thread caching / read-write reordering), and thus throw a NullReferenceException (on _padLock itself) ?

我知道,与监视器锁定 / 锁定有内存屏障的利益,但使用锁佣工如这些时,我不明白为什么这些障碍有保证。在这种情况下,据我了解,构造将不得不进行修改:

I know that locking with Monitor/lock has the benefit of memory barriers, but when using lock helpers such as these I can't see why such barriers are guaranteed. In that case, as far as I understand, the constructor would have to be modified:

public Example()
{
    _padlock = new SyncLock();
    Thread.MemoryBarrier();
}

来源:的了解低锁技术在多线程应用

影响修改汉斯帕桑特表明​​,一个线程的创建意味着内存屏障。因此,如何:

EDIT Hans Passant suggests that the creation of a thread implies a memory barrier. So how about:

var example = new Example();
ThreadPool.QueueUserWorkItem(s => example.ConcurrentMethod());

现在线程不一定创建...

Now a thread is not necessarily created...

推荐答案

没有,你不需要做什么特别的机制保障创建壁垒内存。这是因为几乎所有的机制,用于获取另一个线程执行的方法产生的发布栅栏的调用线程和的 AQUIRE围栏上的障碍的工作线程上的​​障碍(实际上他们可能是全栅栏障碍)。因此,无论 QueueUserWorkItem Thread.Start 将自动插入必要的障碍。你的代码是安全的。

No, you do not need to do anything special to guarentee that memory barriers are created. This is because almost any mechanism used to get a method executing on another thread produces a release-fence barrier on the calling thread and an aquire-fence barrier on the worker thread (actually they may be full fence barriers). So either QueueUserWorkItem or Thread.Start will automatically insert the necessary barriers. Your code is safe.

此外,作为切关心的问题 Thread.sleep代码也产生记忆障碍。因为有些人简单地使用 Thread.sleep代码模拟线交错这很有趣。如果这一策略被用来解决低锁码,然后它很可能掩盖你试图找到问题所在。

Also, as a matter of tangential interest Thread.Sleep also generates a memory barrier. This is interesting because some people naively use Thread.Sleep to simulate thread interleaving. If this strategy were used to troubleshoot low-lock code then it could very well mask the problem you were trying to find.

这篇关于螺纹锁紧佣工的安全使用(关于内存屏障)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆