停止线程的办法

黑娃 2014-10-31 08:44:17
一直不太清楚用什么办法终止线程是比较好的方式,现在归纳如下:
1、设置volatile bool变量,线程在循环条件中判定,其他线程可以通过改变这个状态达到终止线程的目的,不过中止过程会稍稍有点延迟,至少要等到其执行到一次循环结束的点。但这样做能保证要终止的线程释放该释放的非托管变量,很安全,也是我认为最好的中止线程的办法。但它的缺点是:如果到达循环结束之前sleep了,就可能等太久
2、abort(),这个方法并不被推荐,但若遇到上面说的情况,除此之外还能怎样?关于这个abort,虽然说MSDN说捉了一个abort的exception就是了,可是实际情况却不是那么乐观,比如线程正在阻塞访问串口资源,还得先close那个serialPort,同理用interrupt并捕捉了其异常也是不行的,必须释放serialPort,可是如果我不愿意,有其他线程还要用serialPort,那就不好办了,至少我现在还没找到一个办法:既不释放serialPort,又能在一个线程阻塞调用port时,立即终止该线程。
...全文
166 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
黑娃 2014-10-31
  • 打赏
  • 举报
回复
引用 9 楼 sp1234 的回复:
线程操作,我们不允许用 Abort、Suspend 等命令。 而子线程能不能及时且完备地响应(对系统不会造成崩溃性的影响),靠的是规范好设计模式,从设计上把握。
A在默默的和串口通信,确实有循环+阻塞特点,B是用户触发的,虽然没有循环,但是阻塞在串口的read上有20秒,因为规定最迟20返回结果,如果用户不到20秒就想中止,自然就有了中止B的需求,因为AB抢占同一个串口,等待B的20秒时,A不能默默工作。这就是为何我要中止线程B,却想不释放串口的原因。 我目前的解决办法就是不让B中止,一旦启动非得等到它自己超时,却也想不出别的办法了。abort,interrupt都是不行的,会破坏串口。
黑娃 2014-10-31
  • 打赏
  • 举报
回复
引用 9 楼 sp1234 的回复:
线程操作,我们不允许用 Abort、Suspend 等命令。 而子线程能不能及时且完备地响应(对系统不会造成崩溃性的影响),靠的是规范好设计模式,从设计上把握。
听起来你应该很有学问,想跟你请教一下,我对多线程编程的确接触的不多,我都不知道循环、阻塞是多线程编程的大忌。 其实我这里的设计开了两个后台线程,A一直默默的访问serialPort,它就是循环、阻塞,但是阻塞时间很短,可能就是串口返回数据的那点read阻塞,毫秒级别,另外,我也确实不需要它访问太快,为了节约cpu时间,我再每次循环中加入了sleep(1000)。这个线程确实有循环、阻塞的特征,但是我觉得它应该不是什么坏设计。 B线程才是本文我想中止的线程,它没有循环,但是有阻塞,我希望在他阻塞的时候可以中断,但你应该看出来了,AB用了同一个serialPort,我只想中断A却不想释放serialPort,这次引出了我的问题。 希望你能给我以上的设计一点建议,谢谢。
黑娃 2014-10-31
  • 打赏
  • 举报
回复
引用 5 楼 xdashewan 的回复:
[quote=引用 3 楼 falcomavin 的回复:] 你去试一下就知道了,如果你要中止的线程正阻塞在某个串口的read上,却被abort了,是有问题的
你也知道串口是非托管资源,你的线程也是为此开设的,那么你业务既然终止线程,我可以理解为目的是终止串口的读写,那你无论采取何种方式总是要结束串口读写,难道你另一方式还能继续维持串口读写状态,那你终止线程操作的意义何在?[/quote] 确实还有其他线程要用这个port,是做了互斥同步的
  • 打赏
  • 举报
回复
线程操作,我们不允许用 Abort、Suspend 等命令。 而子线程能不能及时且完备地响应(对系统不会造成崩溃性的影响),靠的是规范好设计模式,从设计上把握。
  • 打赏
  • 举报
回复
频繁sleep基本上是古老的“子进程编程”中才用的,因为启动进程非常非常浪费资源,也不存在什么“系统进程池”的东西。 但是如果你设计一个多线程程序,你还动不动sleep,那就是比较“书呆子气”了,你没有自己动脑筋去研究实际情况。 在你的程序中,如果你需要定时,或者你需要等待I/O操作结束,总之不管什么设计,都是可以灵活回调的。只有实在是不得已的时候(输给笨蛋写的程序而又不能绕开的时候),才偶尔会出现“循环、阻塞”的代码。
  • 打赏
  • 举报
回复
引用 楼主 falcomavin 的回复:
一直不太清楚用什么办法终止线程是比较好的方式,现在归纳如下: 1、设置volatile bool变量,线程在循环条件中判定,其他线程可以通过改变这个状态达到终止线程的目的,不过中止过程会稍稍有点延迟,至少要等到其执行到一次循环结束的点。但这样做能保证要终止的线程释放该释放的非托管变量,很安全,也是我认为最好的中止线程的办法。但它的缺点是:如果到达循环结束之前sleep了,就可能等太久
在一个子线程中“循环、阻塞”,这本身就是线程编程设计大忌。先入为主地以这个为控制前提,什么系统控制也不可能做好。
showjim 2014-10-31
  • 打赏
  • 举报
回复
你自己的程序被Abort的话,是没有办法保证其关联的运行状态的,可能造成某些逻辑错误。 系统调用阻塞的线程如果能Abort的话,则可能造成系统的逻辑错误,所以不要想什么其它办法了。 正常情况下所以还是用方案1吧,Sleep仅仅是多消耗一个堆栈内存而已。
xdashewan 2014-10-31
  • 打赏
  • 举报
回复
引用 3 楼 falcomavin 的回复:
你去试一下就知道了,如果你要中止的线程正阻塞在某个串口的read上,却被abort了,是有问题的
你也知道串口是非托管资源,你的线程也是为此开设的,那么你业务既然终止线程,我可以理解为目的是终止串口的读写,那你无论采取何种方式总是要结束串口读写,难道你另一方式还能继续维持串口读写状态,那你终止线程操作的意义何在?
黑娃 2014-10-31
  • 打赏
  • 举报
回复
引用 2 楼 Z65443344 的回复:
serialPort定义成全局变量,不要依赖于线程,不就得了 哪里Abort的,愿意关就关,不愿意关就不关呗
你说的我的是这么做的,但是abort一个正在read串口的线程,真会有问题,而且这个异常是.net内部就捕捉的,我的程序无法处理。
黑娃 2014-10-31
  • 打赏
  • 举报
回复
引用 1 楼 xdashewan 的回复:
没理解你终止线程和你串口关闭有什么直接联系,没有规定过终止线程就一定要终止串口,除非你在线程内创建该串口
你去试一下就知道了,如果你要中止的线程正阻塞在某个串口的read上,却被abort了,是有问题的
於黾 2014-10-31
  • 打赏
  • 举报
回复
serialPort定义成全局变量,不要依赖于线程,不就得了 哪里Abort的,愿意关就关,不愿意关就不关呗
xdashewan 2014-10-31
  • 打赏
  • 举报
回复
没理解你终止线程和你串口关闭有什么直接联系,没有规定过终止线程就一定要终止串口,除非你在线程内创建该串口

17,740

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 .NET Framework
社区管理员
  • .NET Framework社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧