У C # 4.0 BCL SpinLock вращение / блок, когда они не могут получить блокировку? - PullRequest
1 голос
/ 05 июля 2010

С учетом следующего кода:

...
private static SpinLock logLock = new SpinLock(false);
...

private static void ThreadFunc()
{
    bool lockTaken = false;
    logLock.Enter(ref lockTaken)
    {
        try
        {
            // do stuff with during an acquired SpinLock
        }
        finally
        {
            logLock.Exit();
        }
    }
}

Если блок Enter "терпит неудачу" из-за того, что он получает ложь при получении блокировки, разворачивается ли текущий поток как спин-блокировка и ждет, пока не сможет его получить, или этот блок просто обойден, и этот поток проигрывает?

Спасибо

Scott

Ответы [ 2 ]

2 голосов
/ 05 июля 2010

SpinLock по определению заставляет поток вращаться в ожидании получения блокировки, а не блокировки. Enter не «не работает», если не может получить блокировку, он просто ждет.

Единственный случай, когда Enter может потерпеть неудачу, вызывая исключение, это когда владение потоком активировано с использованием нового SpinLock () или нового SpinLock (true). В этом случае выдается исключение, когда поток пытается получить блокировку, которой он уже владеет. В вашем случае это никогда не может произойти, потому что вы создали блокировку с отключенным отслеживанием (SpinLock (false)). Если поток пытается восстановить блокировку, он просто заходит в тупик.

Это описано в документации метода SpinLock.Enter .

1 голос
/ 05 июля 2010

A SpinLock - это просто цикл, пытающийся установить переменную для определенного значения.

Вы можете рассмотреть ее реализацию следующим образом:

public struct SpinLock
{
    private volatile bool _Locked;

    public void Acquire()
    {
        while (_Locked)
            ;
        _Locked = true;
    }

    public void Release()
    {
        _Locked = false;
    }
}

(конечно, приведенный выше код не является потокобезопасным, и я знаю, что это не сигнатура методов класса, это просто вариант псевдокода, чтобы показать, что он делает)

Так что да,если SpinLock уже находится в заблокированном состоянии, попытка получить его будет вращаться до тех пор, пока он не станет доступным.

Также обратите внимание, что по умолчанию (как в вашем примере) структура не отслеживает, кому принадлежитзамок.Это означает, что если поток попытается получить блокировку дважды, он будет взаимоблокировать сам с собой со второй попытки.

Цель SpinLock - блокировка на уровне пользователя с небольшими накладными расходами.Он не добавляет давления GC и не выделяет какой-либо объект синхронизации ядра, это просто структура с несколькими полями.

...