为什么我们不建议暂停一个线程
暂停线程是个坏主意
暂停(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,如果没搞明白原理和适用的场景,最好还是不要使用。
万一,又掉沟里呢?
- 下一篇: 关于窗口风格的设置
- 上一篇: 新的编译开关:生成源码依赖性报告
相关推荐
- 是否需要手动释放一次性定时器?
- Posted on 01月27日
- OpenStack专题:设置hostname并永久生效
- Posted on 01月11日
- 实战经验:MFC非模态对话框的使用
- Posted on 04月22日
- C++小坑一枚:new和deletee未配对使用的后果
- Posted on 11月22日
评论已关闭。