C# 哪个线程将首先进入关键部分?

C# 哪个线程将首先进入关键部分?,c#,.net,multithreading,C#,.net,Multithreading,假设多个线程定期执行下面的DoWork()方法。假设在某个时刻,两个线程几乎同时开始执行此方法,因此两个本地时间戳对象中的一个比另一个大一个刻度 ICollection collection = // ... public void DoWork() { DateTime timestamp = DateTime.Now; lock(collection.SyncRoot) { // critical section } } 如果线程A以等于

假设多个线程定期执行下面的
DoWork()
方法。假设在某个时刻,两个线程几乎同时开始执行此方法,因此两个本地时间戳对象中的一个比另一个大一个刻度

ICollection collection = // ...

public void DoWork()
{
    DateTime timestamp = DateTime.Now;

    lock(collection.SyncRoot)
    {
        // critical section
    }
}
如果线程A以等于t1的时间戳为特征,而线程B以等于t1+1的时间戳t2为特征,那么线程A将首先需要访问临界段


NET如何管理多线程对关键部分的访问?它是否将访问请求放入队列中,以便它们按时间顺序排列?换句话说,是否根据线程访问请求的顺序保证对关键部分的访问?

对于线程的执行顺序以及哪个线程首先获得关键部分,绝对没有任何保证

请注意,即使线程的优先级也不能保证顺序-不同的内核/CPU可以在完全相同的时间以不同的优先级执行线程,任何线程都可以首先到达并获得临界部分


注2:线程也可以被安排在任意时刻执行/等待,因此,同一线程中的两个不同操作彼此相邻并不意味着它们将一个接一个地执行,中间不会有延迟。在您的情况下,这意味着线程A可能会在获得时间戳后立即停止,而计划稍后执行的线程B将很容易获得更晚的时间戳,但首先到达关键部分。

您做出了一个很高的假设,这一假设永远会让程序员在线程方面遇到麻烦。首先获得时间戳的线程肯定也不会首先进入锁。只是几率很高,不是100%。线程被操作系统调度程序抢占。它可以中断任何线程,包括刚开始执行Monitor.Enter()方法调用的线程。然后,调度决策可能会暂停A,并允许B首先获得锁

也不需要调度程序来搞乱订单。执行A的内核可能在其数据缓存中没有“collection”对象引用,在等待内存总线允许执行B的内核抢先运行时,内核将暂停足够长的时间。“种族”一词是恰当的,在这里做出错误的假设会导致代码中出现线程化种族错误


锁背后的机制是由处理器实现的,处理器是唯一能够确保没有“相同时间”的实体。每个多核cpu执行原子指令。您可以在中看到.NET使用的版本。

换句话说,是否根据线程访问请求的顺序保证对关键部分的访问?
NOIt主要基于分配给线程的优先级“线程A首先需要访问关键部分”是什么意思?@MStodd,线程A要求在时间t1访问临界段,线程B要求在时间t2>t1访问临界段,因此我们不能假设或保证访问临界段是按时间戳顺序进行的。如果我想确保与时间戳相关联的任何数据的处理都是按时间戳顺序进行的,那么我应该使用一种策略对要处理的数据进行排序。@enzom83,不确定“使用策略对要处理的数据进行排序”是什么意思。。。看起来不像是对我所说的话的评论,也不像是一个问题。我想按照到达的顺序执行一些任务,而不是按照在共享队列中排队的顺序执行,但我会在这方面写另一个问题,因为这与主题无关。@enzom83。有道理。在最简单的情况下,只要排序队列上的所有读/写操作都受到锁的保护,就可以了。单独的问题是验证您的方法的好主意。