为什么我们不建议暂停一个线程

为什么我们不建议暂停一个线程

作者:BlogUpdater |  时间:2020-08-19 |  浏览:1170 |  评论已关闭 条评论

暂停线程是个坏主意
暂停(Suspend)一个线程,和强行终止(Terminate)一个线程一样糟。
我不准备直接回答这个问题,我准备先问你一些问题,然后看看你的答案是什么?

考虑下面的C#代码:

当你尝试运行这个程序并点击回车按键时,程序会挂起。但是如果你将工作线程中的代码做如下修改:
for (;;) {}
程序就可以顺利运行,这到底咋回事儿呢?

在工作线程中,大部分CPU时间被用来执行System.Console.WriteLine,所以当你执行Thread.Suspend()时,工作线程大概率会停炉在System.Console.WriteLine的代码中。

问题:那么,System.Console.WriteLine的实现是线程安全的吗?
解答:是的,它是线程安全的,我甚至都不用看相关的文档就可以确定这个。主程序没有做任何的线程同步,而是直接从两个不同的线程中调用它,所以,它最好是线程安全的,否则我们在碰到线程暂停的问题之前就已经有大麻烦了。

问题:应该如何在一个对象上施加线程安全机制?
问题:一个线程安全的代码正在运行时,这个时候将线程暂停,会发生什么?
问题:如果在另外一个线程访问同一个对象,会发生什么?

解答:上面提到的问题,是一个通用的问题,不仅限于C#语言。对于Win32或者任何线程模型,都是有着相同的逻辑。
在Win32中,处理器堆内存是一个线程安全的对象,因为在Win32程序中,如果不能灵活方便的访问堆内存,则Win32程序基本就做不了什么大事情,在Win32中暂停一个线程很有可能会造成进程中的死锁。

如果是这样的话,那为什么还要实现SuspendThread这个API呢?
主要是为了考虑使用调试器的场景。
当我们使用调试器调试一个程序的时候,调试器会使用这个API暂停进程中的所有线程,有时候调试器还会用来暂停其他的线程,这样你就可以一次关注一个单独的线程,不会收到其他线程运行的干扰。
因为调试器在另外一个独立的进程,所有这个行为不会导致死锁。

总结
有些Win32 API,如果没搞明白原理和适用的场景,最好还是不要使用。
万一,又掉沟里呢?

标签:

评论已关闭。