English 中文(简体)
当应该和应该时,我利用这一C#级电线控制通过闭路透镜。
原标题:When should & shouldn t I use this C# utility class to control threads via Interlocked

我试图理解这一类文字背后的逻辑,以及当我应该而且不应该使用该类。 任何见解都会受到赞赏。

internal struct SpinLock
{
    private volatile int lockHeld;

    private readonly static int processorCount;

    public bool IsHeld
    {
        get
        {
            return this.lockHeld != 0;
        }
    }

    static SpinLock()
    {
        SpinLock.processorCount = Environment.ProcessorCount;
    }

    public void Enter()
    {
        if (Interlocked.CompareExchange(ref this.lockHeld, 1, 0) != 0)
        {
            this.EnterSpin();
        }
    }

    private void EnterSpin()
    {
        int num = 0;
        while (this.lockHeld != null || Interlocked.CompareExchange(ref this.lockHeld, 1, 0) != 0)
        {
            if (num >= 20 || SpinLock.processorCount <= 1)
            {
                if (num >= 25)
                {
                    Thread.Sleep(1);
                }
                else
                {
                    Thread.Sleep(0);
                }
            }
            else
            {
                Thread.SpinWait(100);
            }
            num++;
        }
    }

    public void Exit()
    {
        this.lockHeld = 0;
    }
}

最新情况:我在源代码中找到了使用样本...... 这表明如何使用上述物体,尽管我不理解“hy”。

    internal class FastReaderWriterLock
    {
        private SpinLock myLock;

        private uint numReadWaiters;

        private uint numWriteWaiters;

        private int owners;

        private EventWaitHandle readEvent;

        private EventWaitHandle writeEvent;

        public FastReaderWriterLock()
        {
        }

        public void AcquireReaderLock(int millisecondsTimeout)
        {
            this.myLock.Enter();
            while (this.owners < 0 || this.numWriteWaiters != 0)
            {
                if (this.readEvent != null)
                {
                    this.WaitOnEvent(this.readEvent, ref this.numReadWaiters, millisecondsTimeout);
                }
                else
                {
                    this.LazyCreateEvent(ref this.readEvent, false);
                }
            }
            FastReaderWriterLock fastReaderWriterLock = this;
            fastReaderWriterLock.owners = fastReaderWriterLock.owners + 1;
            this.myLock.Exit();
        }

private void WaitOnEvent(EventWaitHandle waitEvent, ref uint numWaiters, int millisecondsTimeout)
{
    waitEvent.Reset();
    uint& numPointer = numWaiters;
    bool flag = false;
    this.myLock.Exit();
    try
    {
        if (waitEvent.WaitOne(millisecondsTimeout, false))
        {
            flag = true;
        }
        else
        {
            throw new TimeoutException("ReaderWriterLock timeout expired");
        }
    }
    finally
    {
        this.myLock.Enter();
        uint& numPointer1 = numWaiters;
        if (!flag)
        {
            this.myLock.Exit();
        }
    }
}
    }
最佳回答

SpinLocks, 一般而言,是一种锁的形式,可保持 waiting子的等候(在紧凑的休息条件下进行连续和超重的检查,即“Mommy are we there?),而不是依靠重型、较慢、更慢的路透信号。 通常针对的是预期的等候时间非常短的情况,这些等待时间超过了创建和等待一个职业顾问办公室处理的传统锁的间接费用。 它们的成本高于传统24小时,但这样,在非常短的等待时间上,传统24小时(如Monitor或各种

您的上述法典体现了这一短暂的等候时间概念:

waitEvent.Reset();
// All that we are doing here is setting some variables.  
// It has to be atomic, but it s going to be *really* fast
uint& numPointer = numWaiters;
bool flag = false;
// And we are done.  No need for an OS wait h以及le for 2 lines of code.
this.myLock.Exit();

完全良好的SpinLock ,然而,它只是在第4.0+条中,这样,如果你在较老的版本中工作的话。 互联网框架或从旧版本移出的代码,有人可能已经写出自己的执行。

To answer your question: You should use the built-in SpinLock if you are writing new code on .NET 4.0 or higher. For code on 3.5 or older, especially if you are extending Nesper, I d argue that this implementation is time-tested 以及 appropriate. Only use a SpinLock where you know that the time a thread may wait on it is very small, as in the example above.

EDIT:同执行一样,从Nesper到Nesper。 埃斯佩雷中心图书馆网港口:

以及

https://svn.codehaus.org/esper/esper/tagsnet/release_1.12.0_beta_1/trunk/NEsper/compat/FastReaderWriterLock.cs

我可以证实,Nesper早在之前就存在。 NET 框架4,从而解释了是否需要一个家庭-SpinLock。

问题回答

似乎原始作者希望更快地采用<代码>ReaderWriterLock。 这一旧的阶层令人痛苦地缓慢。 我本人的测试(我很久以前曾做过)表明,RWL有大约8x个老便衣(<>24>。 细微改进了物品(尽管与<条码><>锁/代码>相比,它仍有大约2x的间接费用)。 在此,我要说的是,海关编码是 d的,只是使用新的<代码>。 ReaderWriterLockSlim category.

但是,由于值得做的是,我要解释一下其中一些习俗:<编码>SpinLock。

  • Interlocked.CompareExchange is .NET s version of a CAS operation. It is the most fundamental synchronization primitive. You can literally build everything else from this single operation including your own custom Monitor-like class, reader writer locks, etc. Obviously it was used here to create a spin lock.
  • Thread.Sleep(0) yields to any thread of with the same or higher priority on any processor.
  • Thread.Sleep(1) yields to any thread on any processor.
  • Thread.SpinWait puts the thread into a tight loop for the specified number of iterations.

虽然这在法典中并未使用,但你指出,还有另一个有用的机制,用以建立锁锁(或其他低锁战略)。

  • Thread.Yield yields to any thread on the same processor.

微软在其高度同步的同步机制和收集工作中使用所有这些电话。 如果您填写了<代码>SpinLock,SpinWait,ManualResetEventSlim,你将看到与这些话相呼应的相当复杂的歌曲和舞蹈......这比你所写的法典更为复杂。

再说一遍, d《习俗守则》和刚刚使用的<代码>ReaderWriterLockSlim,而不是该习惯<代码>。 班级。


By the way,this.lock ∗ E/CN.6/2009/1。 应从<代码>24小时起产生汇编警报。 a 价值类型:





相关问题
Anyone feel like passing it forward?

I m the only developer in my company, and am getting along well as an autodidact, but I know I m missing out on the education one gets from working with and having code reviewed by more senior devs. ...

NSArray s, Primitive types and Boxing Oh My!

I m pretty new to the Objective-C world and I have a long history with .net/C# so naturally I m inclined to use my C# wits. Now here s the question: I feel really inclined to create some type of ...

C# Marshal / Pinvoke CBitmap?

I cannot figure out how to marshal a C++ CBitmap to a C# Bitmap or Image class. My import looks like this: [DllImport(@"test.dll", CharSet = CharSet.Unicode)] public static extern IntPtr ...

How to Use Ghostscript DLL to convert PDF to PDF/A

How to user GhostScript DLL to convert PDF to PDF/A. I know I kind of have to call the exported function of gsdll32.dll whose name is gsapi_init_with_args, but how do i pass the right arguments? BTW, ...

Linqy no matchy

Maybe it s something I m doing wrong. I m just learning Linq because I m bored. And so far so good. I made a little program and it basically just outputs all matches (foreach) into a label control. ...