zthread学习 实例九 任务终止(二)——中断方式
2015-05-19 21:26
323 查看
引起线程变为阻塞状态的原因有:
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
plaincopy
#include "stdafx.h"
#include "zthread/FastMutex.h"
#include "zthread/CountedPtr.h"
#include "zthread/Runnable.h"
#include <iostream>
#include <vector>
#include <ctime>
#include "Display.h"
using namespace ZThread;
using namespace std;
const double PI = 3.1415926;
const double e = 2.7182818;
class NeedCleanup
{
public:
NeedCleanup(int idn = 0) : id(idn)
{
cout << " NeedCleanup : " << id << endl;
}
~NeedCleanup()
{
cout << " ~NeedCleanup : " << id << endl;
}
private:
int id;
};
class Blocked : public Runnable
{
public:
Blocked() : d(0.0){}
void run()
{
try
{
while (!Thread::interrupted())
{
//point1 阻塞线程的终止 抛出异常退出
NeedCleanup(1);
cout << "Sleep" <<endl;
Thread::sleep(5000);
//point2 非阻塞线程的终止 通过while()条件退出
NeedCleanup(2);
cout <<"Calculating" <<endl;
for (int i= 0; i <100000; i++) //大量运算,使之处于非阻塞的情况下
{
d = d + (PI + e) / (double)i;
}
}
cout << "exit via while() test" <<endl;
}
catch (Interrupted_Exception& e)
{
cout << "exit via Interrupted_Exception test" <<endl;
cerr << e.what() <<endl;
}
}
private:
volatile double d;
};
int _tmain(int argc, _TCHAR* argv[])
{
try
{
Thread t(new Blocked);
//Thread::sleep(2000); //阻塞线程的终止
Thread::sleep(5010); //非阻塞线程的终止
t.interrupt(); //发出中断
cin.get();
}
catch (Synchronization_Exception& e)
{
cerr << e.what() <<endl;
}
return 0;
}
为了保证不因退出而出现不一致的状态,所有资源获取都应封装在基于栈的对象中,以便无论run()如何退出,对象的析构都会被调用。
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
plaincopy
#include "stdafx.h"
#include "zthread/FastMutex.h"
#include "zthread/CountedPtr.h"
#include "zthread/Runnable.h"
#include <iostream>
#include <vector>
#include <ctime>
#include "Display.h"
using namespace ZThread;
using namespace std;
const double PI = 3.1415926;
const double e = 2.7182818;
class NeedCleanup
{
public:
NeedCleanup(int idn = 0) : id(idn)
{
cout << " NeedCleanup : " << id << endl;
}
~NeedCleanup()
{
cout << " ~NeedCleanup : " << id << endl;
}
private:
int id;
};
class Blocked : public Runnable
{
public:
Blocked() : d(0.0){}
void run()
{
try
{
while (!Thread::interrupted())
{
//point1 阻塞线程的终止 抛出异常退出
NeedCleanup(1);
cout << "Sleep" <<endl;
Thread::sleep(5000);
//point2 非阻塞线程的终止 通过while()条件退出
NeedCleanup(2);
cout <<"Calculating" <<endl;
for (int i= 0; i <100000; i++) //大量运算,使之处于非阻塞的情况下
{
d = d + (PI + e) / (double)i;
}
}
cout << "exit via while() test" <<endl;
}
catch (Interrupted_Exception& e)
{
cout << "exit via Interrupted_Exception test" <<endl;
cerr << e.what() <<endl;
}
}
private:
volatile double d;
};
int _tmain(int argc, _TCHAR* argv[])
{
try
{
Thread t(new Blocked);
//Thread::sleep(2000); //阻塞线程的终止
Thread::sleep(5010); //非阻塞线程的终止
t.interrupt(); //发出中断
cin.get();
}
catch (Synchronization_Exception& e)
{
cerr << e.what() <<endl;
}
return 0;
}
为了保证不因退出而出现不一致的状态,所有资源获取都应封装在基于栈的对象中,以便无论run()如何退出,对象的析构都会被调用。
相关文章推荐
- zthread学习 实例九 任务终止(二)——中断方式
- zthread学习 实例八 任务终止(一)——观赏植物园
- zthread学习 实例八 任务终止(一)——观赏植物园
- zthread学习 实例五 非任务对象的生存期
- zthread学习 实例五 非任务对象的生存期
- Think PHP 学习笔记 10.查询方式实例演示
- oracle学习之asm实例的数据库启动方式
- Spring学习之实例化bean的三种方式
- zthread学习 实例十 线程间的协助(一)
- Java学习-014-文本文件写入实例源代码(两种写入方式)
- 工作流学习——Activiti流程实例、任务管理四步曲
- activiti学习--13:组任务分配方式2--使用流程变量
- Quartz.NET 2.0 学习笔记(5) :实例创建Windows服务实现任务调度
- 【Spring学习】spring定时任务的实现方式
- 工作流学习——Activiti流程实例、任务管理四步曲
- 工作流学习——Activiti流程实例、任务管理四步曲
- PHP 开发 APP 接口 学习笔记与总结 - APP 接口实例 [4] 首页 APP 接口开发方案 ③ 定时读取缓存方式
- 使用51单片机采用中断方式进行串口通信的学习记录:
- zthread学习 实例三 使用Executor器来执行线程
- CPU处理多任务——中断与轮询方式比较