gpt4 book ai didi

c# - lock() 是否保证按请求的顺序获取?

转载 作者:IT王子 更新时间:2023-10-29 03:45:43 27 4
gpt4 key购买 nike

当多个线程请求同一对象上的锁时,CLR 是否保证将按照请求的顺序获取锁?

我写了一个测试,看看这是不是真的,它似乎表明是的,但我不确定这是否是确定的。

class LockSequence
{
private static readonly object _lock = new object();

private static DateTime _dueTime;

public static void Test()
{
var states = new List<State>();

_dueTime = DateTime.Now.AddSeconds(5);

for (int i = 0; i < 10; i++)
{
var state = new State {Index = i};
ThreadPool.QueueUserWorkItem(Go, state);
states.Add(state);
Thread.Sleep(100);
}

states.ForEach(s => s.Sync.WaitOne());
states.ForEach(s => s.Sync.Close());
}

private static void Go(object state)
{
var s = (State) state;

Console.WriteLine("Go entered: " + s.Index);

lock (_lock)
{
Console.WriteLine("{0,2} got lock", s.Index);
if (_dueTime > DateTime.Now)
{
var time = _dueTime - DateTime.Now;
Console.WriteLine("{0,2} sleeping for {1} ticks", s.Index, time.Ticks);
Thread.Sleep(time);
}
Console.WriteLine("{0,2} exiting lock", s.Index);
}

s.Sync.Set();
}

private class State
{
public int Index;
public readonly ManualResetEvent Sync = new ManualResetEvent(false);
}
}

打印:

Go entered: 0

0 got lock

0 sleeping for 49979998 ticks

Go entered: 1

Go entered: 2

Go entered: 3

Go entered: 4

Go entered: 5

Go entered: 6

Go entered: 7

Go entered: 8

Go entered: 9

0 exiting lock

1 got lock

1 sleeping for 5001 ticks

1 exiting lock

2 got lock

2 sleeping for 5001 ticks

2 exiting lock

3 got lock

3 sleeping for 5001 ticks

3 exiting lock

4 got lock

4 sleeping for 5001 ticks

4 exiting lock

5 got lock

5 sleeping for 5001 ticks

5 exiting lock

6 got lock

6 exiting lock

7 got lock

7 exiting lock

8 got lock

8 exiting lock

9 got lock

9 exiting lock

最佳答案

IIRC,极有可能按此顺序排列,但不能保证。我相信至少在理论上存在线程会被虚假唤醒的情况,请注意它仍然没有锁,然后转到队列的后面。这可能只适用于 Wait/Notify ,但我暗暗怀疑它也用于锁定。

绝对不会依赖它 - 如果您需要按顺序发生事情,请构建一个 Queue<T>或类似的东西。

编辑:我刚刚在 Joe Duffy 的 Concurrent Programming on Windows 中找到了这个基本上同意:

Because monitors use kernel objects internally, they exhibit the same roughly-FIFO behavior that the OS synchronization mechanisms also exhibit (described in the previous chapter). Monitors are unfair, so if another thread tries to acquire the lock before an awakened waiting thread tries to acquire the lock, the sneaky thread is permitted to acquire a lock.

“roughly-FIFO”位是我之前的想法,“sneaky thread”位进一步证明您不应该对 FIFO 排序做出假设。

关于c# - lock() 是否保证按请求的顺序获取?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4228864/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com