1、线程的停止
线程的停止:当return语句被执行时,表示该线程正常退出。
int Routine()
{
printf("do something \n");
return 0; // 线程的主函数退出
}
return语句被执行、Routine()返回、线程退出
实例中如果没有getchar()
则在main()函数中,执行后直接退出,即主线程退出,则我们创建的线程没有办法执行。
2、线程的异常停止
异常停止:主线程(主程序)退出的时候,有线程正在运行,所有线程都被立即终止。
这种终止是不正常的: 因为它可能正在处理某个任务,从而造成了不完整数据。
比如:
它正在录制一个文件,录了半个小时,数据还没保存,不能突然直接关闭啊!
2.1 线程的异常停止
int main()
{
Buddhist b;
b.Run(); //线程1
Confucian c;
c.Run(); //线程2
getchar(); //输入回车 主线程退出
return 0;
}
如何让其正常终止呢?
2.2 线程的正常终止
一般的方法:首先,设置标识量 (如 m_quitflag)在线程主函数Routine()里,检查m_quitflag,当m_quitflag为true时意味着应该退出。
线程在处理其任务的时候,不停地检测标识量,及时地退出线程。 在退出的时候,保存当前任务的进度,以便下次继续。或保存所有其他需要保存的数据。
2.2.1 添加标志量,用于控制线程的退出
//定义一个类
class Buddhist :public OS_Thread
{
private:
virtual int Routine()
{
//线程体:执行他的任务
//每次执行前检测线程是否退出
for (int i = 0; !m_quitflag && i < 100; i++)
{
printf("和尚念经。。。\n");
OS_Thread::Sleep(1); //静态函数
}
//保存数据,善后工作
//...
printf("保存已经完成数据,善后工作 Task Exit.... \n");
return 0; //线程正常退出
}
public:
bool m_quitflag;
};
//不会执行到:printf("保存已经完成数据,善后工作 Task Exit.... \n");
2.2.2 仅仅设置标识量还不够,还需要等待线程退出
int main()
{
Buddhist b;
b.m_quitflag = false; //不退出
b.Run(); //线程1
Confucian c;
c.Run(); //线程2
b.m_quitflag = true; //退出
OS_Thread::Join(&b); // 使用静态函数Join(),来等待目标线程退出。
getchar(); //输入回车 主线程退出
return 0;
}
使用静态函数Join(),来等待目标线程退出。
2.2.3 Join()函数的作用:
- (1)等待目标线程的退出
- (2)回收这个线程的相关系统资源(记住线程的个数是受限的)
Join的调用:当一个线程A要退出时,由另一个线程调用Join来回收线程A。
注意:Join不能回收自已!
int Routine()
{
Join(this); // 错!!一个线程是不能Join自己的
return 0;
}
由主线程、或者任何的另外一个线程来执行Join
(1)回收目标线程相关的系统资源
(2)如果目标线程尚未退出,则一直等待,直到其退出。
首先,通知其退出然后,等待其退出(它的退出、善后是需要一定时间的)
Join的书写位置:不能只看字面上的位置,而是要从运行时的角度来看待问题。