zthread学习 实例九 任务终止(二)——中断方式

引起线程变为阻塞状态的原因有:

1、调用了sleep(),线程进入休眠状态。

2、调用了wait(),挂起了线程的运行。

3、线程正在等待某个I/0操作完成(此时中断是不会出现的)。

4、线程在尝试进入一段被一个互斥锁保护的代码块,而那个互斥锁已经被其他线程获得。

 


终止一个阻塞线程和终止一个非阻塞线程的方式有很大的不同。

 

终止一个阻塞线程 通常 的做法是,首先唤醒它,然后按终止一个非阻塞线程的方式来终止,但这样线程会多执行了一些代码。

 

有时需要在某个线程处于阻塞状态时 立即 终止它。ZThread库使用抛异常的方式来解决立即终止 阻塞 线程。因为从被阻塞的任务中离开时,可能需要销毁与之相关的对象并清理有关资源,正因为这样在run()中间跳出更像是抛出一个异常。在run()函数包含try模块,在响应异常的catch语句中清理有关资源。

 

interrupt()函数用来给线程设置中断状态,一个使用了中断状态设置的线程,如果已经被阻塞或尝试进行阻塞时将会抛出一个Interrupted_Exception异常。当异常被抛出或调用了intertupted()时,中断状态重新被设置。

 

中断状态可以通过调用interrupt()进行设置。调用interrupted()来检查中断状态(不仅能告知interrupt()是否被调用,还会清除当前的中断状态,以确保不会两次通知正被中断的任务),interrupted()会用一个Interrupted_Exception异常来通知一个已经阻塞的线程,或用一个成功的返回值来通知一个非阻塞的线程。下面例子显示了当设置中断状态时,run()函数中处理阻塞和非阻塞两种可能性的情况:

[cpp]  view plain copy
  1. #include "stdafx.h"  
  2. #include "zthread/FastMutex.h"  
  3. #include "zthread/CountedPtr.h"  
  4. #include "zthread/Runnable.h"  
  5. #include <iostream>  
  6. #include <vector>  
  7. #include <ctime>  
  8. #include "Display.h"  
  9. using namespace ZThread;  
  10. using namespace std;  
  11. const double PI = 3.1415926;  
  12. const double e = 2.7182818;  
  13. class NeedCleanup  
  14. {  
  15. public:  
  16.     NeedCleanup(int idn = 0) : id(idn)  
  17.     {  
  18.         cout << " NeedCleanup : " << id << endl;  
  19.     }  
  20.     ~NeedCleanup()  
  21.     {  
  22.         cout << " ~NeedCleanup : " << id << endl;  
  23.     }  
  24. private:  
  25.     int id;  
  26. };  
  27. class Blocked : public  Runnable  
  28. {  
  29. public:  
  30.     Blocked() : d(0.0){}  
  31.       
  32.     void run()  
  33.     {  
  34.         try  
  35.         {  
  36.             while (!Thread::interrupted())  
  37.             {  
  38.                 //point1    阻塞线程的终止     抛出异常退出  
  39.                 NeedCleanup(1);  
  40.                   
  41.                 cout << "Sleep" <<endl;  
  42.                 Thread::sleep(5000);  
  43.                   
  44.                 //point2    非阻塞线程的终止    通过while()条件退出  
  45.                 NeedCleanup(2);  
  46.                 cout <<"Calculating" <<endl;  
  47.                 for (int i= 0; i <100000; i++)   //大量运算,使之处于非阻塞的情况下  
  48.                 {  
  49.                     d = d + (PI + e) / (double)i;  
  50.                 }  
  51.             }  
  52.             cout << "exit via while() test" <<endl;  
  53.         }  
  54.         catch (Interrupted_Exception& e)  
  55.         {  
  56.             cout << "exit via Interrupted_Exception test" <<endl;  
  57.             cerr << e.what() <<endl;  
  58.         }  
  59.     }  
  60. private:  
  61.     volatile double d;  
  62. };  
  63. int _tmain(int argc, _TCHAR* argv[])   
  64. {  
  65.     try  
  66.     {  
  67.         Thread t(new Blocked);    
  68.         //Thread::sleep(2000);      //阻塞线程的终止  
  69.         Thread::sleep(5010);        //非阻塞线程的终止  
  70.           
  71.         t.interrupt();      //发出中断  
  72.           
  73.         cin.get();  
  74.     }  
  75.     catch (Synchronization_Exception& e)  
  76.     {  
  77.         cerr << e.what() <<endl;          
  78.     }  
  79.     return 0;  
  80. }  
 

为了保证不因退出而出现不一致的状态,所有资源获取都应封装在基于的对象中,以便无论run()如何退出,对象的析构都会被调用。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值