我有以下代码
class Program
{
static SpinLock sl = new SpinLock();
public static void Foo(object arg)
{
bool r = false;
sl.Enter(ref r);
}
public static void Main(string[] args)
{
bool r = false;
sl.Enter(ref r);
ThreadPool.QueueUserWorkItem(Foo);
Thread.Sleep(5000);
sl.Exit();
Thread.Sleep(5000);
}
}当我执行它时,我在整个程序运行过程中看到~0%的CPU负载。我本来希望看到一些CPU因在sl.Enter()调用中旋转而消耗,但事实并非如此。
根据SpinLock源的说法,它在引擎盖下使用了SpinWait,这反过来又在某个时候调用了Thread.Sleep(1)。
这是否意味着SpinLock和SpinWait都不是真正的“附带程序”,而是仍然依靠操作系统调度器来获得一些CPU份额?
编辑
这个问题可以用以下方式重新表述:
使用繁忙的循环确保一个线程释放锁和另一个线程获取锁之间的时间是最小的。在这方面,我可以依赖SpinLock/SpinWait吗?据我所知,答案是no,因为它做Sleep至少1微秒,锁可能在这段时间内被释放。
发布于 2021-12-10 00:25:43
关于您编辑过的问题,是的,忙着旋转会给线程之间的通信带来最低的延迟,但是您将通过消耗CPU时间来支付。
另一方面,您可以使用SpinWait,它的侵略性较低,或者可以在两者之间编写代码,例如这。
这取决于你对延迟的重视程度,以及你需要节省多少核心。
https://stackoverflow.com/questions/70294914
复制相似问题