Thread.Sleep(0)不能像描述的那样工作?
我目前正在阅读这篇关于线程的优秀文章 ,并阅读以下文字:
Thread.Sleep(0)立即放弃线程的当前时间片,自愿将CPU交给其他线程。
我想测试这个,下面是我的测试代码:
static string s = ""; static void Main(string[] args) { //Create two threads that append string s Thread threadPoints = new Thread(SetPoints); Thread threadNewLines = new Thread(SetNewLines); //Start threads threadPoints.Start(); threadNewLines.Start(); //Wait one second for threads to manipulate string s Thread.Sleep(1000); //Threads have an infinite loop so we have to close them forcefully. threadPoints.Abort(); threadNewLines.Abort(); //Print string s and wait for user-input Console.WriteLine(s); Console.ReadKey(); }
threadPoints和threadNewLines运行的函数:
static void SetPoints() { while(true) { s += "."; } } static void SetNewLines() { while(true) { s += "n"; Thread.Sleep(0); } }
如果我正确理解Thread.Sleep(0),输出应该是这样的:
............ | .............. | ................ | <- End of console .......... | ............. | ............... |
但我得到这个作为输出:
....................| ....................| .... | | | ....................| ....................| ................. | |
正如许多程序员强烈推荐的那样,在post开头提到的文章,我只能假设我对Thread.Sleep(0)的理解是错误的。 所以,如果有人能澄清,我会非常感激。
什么thread.sleep(0)是释放cpu来处理其他线程,但这并不意味着另一个线程不能是当前线程。 如果您尝试将上下文发送到另一个线程,请尝试使用某种信号。
如果您可以访问仅具有单个核心/处理器的计算机(或可能是VM),请尝试在该计算机上运行代码。 您可能会对结果的变化感到惊讶。 仅仅因为两个线程引用相同的变量“s”,并不意味着它们实际上同时引用相同的值,因为现代多核(甚至只是并行管道)CPU可能会出现各种级别的缓存。 如果你想看看如何在不考虑缓存问题的情况下如何工作,请尝试将每个s +=
表达式包装在一个lock
语句中。
如果您将控制台的宽度扩展为比当前大5倍,那么您将看到您所期望的,线条未达到控制台宽度。 问题是一个时间片实际上很长。 因此,要使用普通控制台获得预期效果,您必须减慢Points线程,但不使用Sleep。 而不是while (true)
循环尝试这个
for (int i = 0;; i++) { if (int % 10 == 0) s += "."; }
要减慢线程速度,请使用更大的数字替换数字10。
处理器处理的下一个线程是随机线程,它甚至可以是你刚才调用Thread.Sleep(0)的同一个线程。 为了确保下一个线程不是同一个线程,你可以调用Thread.Yield()并检查它的返回结果 – 如果os有另一个可以运行true的线程,则返回false。
你应该(几乎) 永远不会中止线程 。 最好的做法是告诉他们死亡 (自杀)。
这通常通过设置一些布尔变量来完成,并且线程应检查其值是否继续执行。
您正在设置名为“s”的字符串变量。 你将在竞争条件下招致。 字符串不是线程安全的 。 您可以将操作它的操作包装在一个锁中,或者使用一个线程安全的内置类型。
在文档中,请始终注意了解您使用的类型是否是线程安全的。
因此,您不能依赖于您的结果,因为您的程序不是线程安全的 。 如果您多次运行该程序,我的猜测是您将获得不同的输出。
注意:使用布尔值共享某些状态以取消线程时,请确保将其标记为volatile 。 JIT可能会优化代码,而不会查看其更改的值。
上述就是C#学习教程:Thread.Sleep(0)不能像描述的那样工作?分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/cdevelopment/1000378.html