Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.net 什么';Thread.SpinWait方法的目的是什么?_.net_Multithreading - Fatal编程技术网

.net 什么';Thread.SpinWait方法的目的是什么?

.net 什么';Thread.SpinWait方法的目的是什么?,.net,multithreading,.net,Multithreading,从这个角度来看,它的目的并不明确 它可以用来模拟密集的CPU计算测试吗?如果您相信您等待的条件很快就会实现,那么它的目的是进行“廉价”等待。通常,如果您正在等待某个线程,您会让该线程进入睡眠状态,处理器/操作系统将上下文切换到另一个线程。上下文切换并不是特别便宜,所以如果您对情况有深入的了解,并且相信等待比上下文切换更便宜,那么您可以选择等待 我的建议是:如果你需要问,你不需要使用它。(我自己从来都不想要它。)基本上,它是在极少数情况下非常有用的东西之一,但大多数人都应该远离它。就我而言(我很乐

从这个角度来看,它的目的并不明确

它可以用来模拟密集的CPU计算测试吗?

如果您相信您等待的条件很快就会实现,那么它的目的是进行“廉价”等待。通常,如果您正在等待某个线程,您会让该线程进入睡眠状态,处理器/操作系统将上下文切换到另一个线程。上下文切换并不是特别便宜,所以如果您对情况有深入的了解,并且相信等待比上下文切换更便宜,那么您可以选择等待

我的建议是:如果你需要问,你不需要使用它。(我自己从来都不想要它。)基本上,它是在极少数情况下非常有用的东西之一,但大多数人都应该远离它。

就我而言(我很乐意更正!),自旋等待的唯一用途是在实现锁定或线程间回调机制时。而且这两种方法都不应该手动完成(通常),因为它们已经存在


当您锁定了一个资源,而另一个线程请求对其进行同步访问时,它基本上必须等待第一个线程完成使用。这种等待可以通过简单的循环旋转来完成(或者Jon提到的睡眠+上下文切换)。

不。它可以替代非常短期的睡眠呼叫

当您执行多线程锁定时,如果您试图获取的资源已经被锁定,您通常会进入睡眠状态,等待它释放。当您这样做时,您将放弃计划程序分配给您的剩余时间来使用处理器,以便其他人可以尝试。 通常情况下,这很好,特别是对于长时间的等待(如等待IO),当您等待磁盘主轴旋转时,其他进程的负载可以在CPU上运行

然而,有时候,你只是在等待一点点时间。在这些情况下,您通常会放弃剩余的时间,等待所有其他线程完成它们的任务,然后再尝试。。所以你可以作弊,而不是等待,你坐在那里不断地以“我们快到了吗?”的方式投票。如果锁只保留了剩余时间的一小部分,那么这将成为一种非常有效的等待方式,它也非常有效,因为调度程序不必重新安排所有其他线程,以使用您在正常等待时放弃的时间

显然,如果你每次想要锁的时候都旋转,你不会很受欢迎,你的应用程序会变得迟钝,使用100%的CPU,但在适当的时候,它会使应用程序更灵敏


如果你现在在想“我应该什么时候使用它?”这是一个棘手的问题-如果你有一个资源经常很快被锁定和解锁,那么围绕它的旋转锁而不是等待是一个好主意(然后测试你的应用程序的性能),如果你尝试旋转一小段时间,然后回到正常的等待,这也是一个合理的方法。但一般来说,您永远不需要使用它。

顺便说一句,Microsoft已经从Windows 7中删除了线程调度程序自旋锁机制,因为它不能很好地扩展到多核CPU。看一看:

我想这一条与“除非你已经测量并发现有问题……”这一类是一致的。jon skeet因此默认情况下,你会建议只使用lock(obj),只有在通过基准测试确定它对你的场景更快时才使用spinwait?@rolls:是的,绝对如此。这是一个非常小的功能。假设我们希望平均实现50毫秒的延迟,那么我们应该指定多少次迭代?
SpinWait
很少会让您停留在100%的CPU利用率。这是因为它开始导致线程屈服或睡眠,如果它旋转太长时间。具体而言,如果旋转次数大于或等于10,则每第19次旋转将
休眠(1)
,每第4次旋转将
休眠(0)
,并且
产量
当且仅当确定下一次旋转具有产量潜力时。它可以
睡眠
在多处理器系统上随时产生
,无需等待最初的10次旋转。在单处理器系统上,如果自旋计数小于等于10,它将只
休眠
产生
。@MichaelJ.Gray:您将
线程.SpinWait()
(问答)与
var sw=new SpinWait()混淆了;sw.SpinOnce()内部旋转计数到10…@CharlesOkwuagwu持续数十毫秒,您可能最好使用一个简单的线程。睡眠。@StephenKennedy“持续数十毫秒”,您绝对会(不可能)使用一个简单的线程。睡眠。现代处理器可以在数十毫秒内在单个内核上执行数百万条指令。一个例外是在游戏引擎的
Render()
周期内限制帧速率。其他
Sleep()
机制都不能很好地保证何时重新切换。@基本正确,但通常的做法是在渲染周期中跳过圈,而不是使用显式(嵌套)等待循环。效果当然是一样的,它说他们已经去掉了Windows中使用的一个自旋锁——dispatcher自旋锁。