唤醒已存在的线程:(

jiajian008 2006-08-12 04:22:40
在另一个窗体中建立了一个线程CircleThread,这个线程创建后休眠,需要resume后才能执行。然后,
if not Assigned(CircleThread) then
CircleThread := TCircleThread.Create(2, 2, 2, '2', '2'); 这种情况能OK
else begin
CircleThread.X := 1; 这种情况不能执行
CircleThread.Y := 1;
CircleThread.radius := 1;
CircleThread.color := '1';
CircleThread.ADeviceNo := '1';
end;
CircleThread.Resume;

现在,没有线程创建线程后执行时是正确的;
但是线程已存在时,线程都不执行;
是哪里有问题,不是写了CircleThread.Resume用来唤醒线程了吗?

...全文
488 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
jiajian008 2006-08-15
  • 打赏
  • 举报
回复
还有,我现在要启多线程,这样一来会有多个线程对象存在,那我怎么释放呢,需要不需要释放呢?
僵哥 2006-08-15
  • 打赏
  • 举报
回复
既然是使用TThread做为基类,在线程多不便管理的情况下可以考虑使用FreeOnTerminate属性,让线程运行完毕就自行释放,当然使用这种方式,你必须得保证在线程执行体当中不出现重大的异常,而使得线程调用代码,能对线程进行管控.
僵哥 2006-08-14
  • 打赏
  • 举报
回复
首先要明确,当线程处于Sleep(Suspended)状态下时,你需要唤醒(Resume),但是此时可能存在三种情况:
一、该线程对象不存在(Not Assigned),那么就需要明确是否需要再创建该线程对象,如果不需要,可能得抛出异常,给操作员或者主操作函数/过程一个异常(Exception);
二、该线程对象存在但是线程执行体已经结束执行,此时就需要进行CloseHandle(实际上使用TThread,应该是调用Free方法),之后同情况一一致处理;
三、该线程确实处于睡眠(Sleep,Suspended)状态,则直接调用ResumeThread(对于使用TThread类,包括子类对象应当调用其自身的Resume方法),通常Resume也并不一定会成功,则对于使用ResumeThread,则可以根据返回值进行处理,但是对于使用TThread.Resume,则另做处理,通常情况下都会认为它是成功的,这里得看个人的严谨态度,同时也视程序的可靠性要求而来,可靠性要求越高,则更需要注意各种异常的判断,特别是任何一个有返回值的函数调用都需要对返回值进行判断并加以处理,这也是一个习惯问题。对于没有返回值的过程调用通常会认为是必定成功的,但是也要视情况而定,必要时尽可能通过其它途径进行异常检验,以避免不必要的问题发生,并且通常在这种过程的调用出现问题是最能进行debug的。

if not Assigned(AlarmCircleThread) then
begin
AlarmCircleThread := TAlarmCircleThread.Create(2, 2, 2, '2', '2');
AlarmCircleThread.Resume;//这里使用了Resume说明TAlarmCircleThread创建时是处于睡眠状态的
end
else begin//线程对象仍然存在
IsLay :=GetExitCodeThread(AlarmCircleThread.Handle,ExitCode);
if IsLay then begin
if ExitCode=STILL_ACTIVE then begin
ResumeThread(AlarmCircleThread.Handle);//这里该使用AlarmCircleThread.Resume;
showmessage('线程在活动中')
end
else
showmessage('线程已终止terminate,但句柄未释放free');//这里由于线程的执行过程已经结束,华伦再世也无法让它起死回生,所以就该让它安静地去
//Begin=====================Modify
AlarmCircleThread.Free;
AlarmCircleThread := TAlarmCircleThread.Create(2, 2, 2, '2', '2');
AlarmCircleThread.Resume;
//End=======================Modify
end
else begin
//CloseHandle(AlarmCircleThread.Handle);//这里面不该是关闭句柄,这里是由于调用GetExitCodeThread失败而引发的,所以应当使用GetLastError来判断所产生的错误
//showmessage('句柄已释放');
//Begin=====================Modify
raise Exception.CreateFmt('Error occured when call GetExitCodeThread! ThreadID:%d,Error Code:%d',[AlarmCircleThread.ThreadID,GetLastError]);
//End=======================Modify

end;
//ShowMessage('线程对象还存在');
end;
jiajian008 2006-08-14
  • 打赏
  • 举报
回复
高手们,快来啊。。。。
僵哥 2006-08-13
  • 打赏
  • 举报
回复
GetExitCodeThread(ThreadHandle,ExitCode)
来取得ExitCode,如果ExitCode=STILL_ACTIVE
表示线程还存在,对于存在的线程,则可以使用ResumeThread(ThreadHandle)来唤醒线程,如果线程仍然处于运行状态,则会返回错误具体的自己去看相关的API的返回值。
僵哥 2006-08-13
  • 打赏
  • 举报
回复
如果处于STILL_ACTIVE状态,则使用ResumeThread(线程句柄),即可,但是注意的是需要相当的权限。如果不是,则只能进行CloseHandle,再CreateThread.
jiajian008 2006-08-13
  • 打赏
  • 举报
回复
if not Assigned(AlarmCircleThread) then
begin
AlarmCircleThread := TAlarmCircleThread.Create(2, 2, 2, '2', '2');
AlarmCircleThread.Resume;
end
else begin
IsLay :=GetExitCodeThread(AlarmCircleThread.Handle,ExitCode);
if IsLay then begin
if ExitCode=STILL_ACTIVE then begin
ResumeThread(AlarmCircleThread.Handle);
showmessage('线程在活动中')
end
else
showmessage('线程已终止terminate,但句柄未释放free');
end
else begin
CloseHandle(AlarmCircleThread.Handle);
showmessage('句柄已释放');

end;
ShowMessage('线程对象还存在');
end;
我是这样写的,但是还不能达到效果:(
jiajian008 2006-08-13
  • 打赏
  • 举报
回复
我刚测试了一下楼上的,有点明白了,是线程对象还存在,而这时候线程有时正在允许,有时已经释放了句柄,我怎么去处理它,让这个已经存在的线程对象再一次执行。。。
jiajian008 2006-08-12
  • 打赏
  • 举报
回复
这个FreeOnTerminated是设置为True了,那我线程对象存在时,怎么才能让线程再次运行?
andyzhou1101 2006-08-12
  • 打赏
  • 举报
回复
你的线程的FreeOnTerminated是不是设置为True了啊
就是说你的线程第一次执行完就退出了
再Resume当然没有效果了
BlueTrees 2006-08-12
  • 打赏
  • 举报
回复
废话,线程不是一组函数,它是一串操作的过程,一旦线程函数退出了,线程也就结束了。

线程已经存在,那是线程对象,不一定线程还存在!

你好好看看Delphi关于线程的说明。特别是Execute如何设计!

线程挂起后才能Resume,但是,线程退出后就不能Resume
从零开始讲述Java多线程的核心知识,通过板书和一步一步画图的方式,引领大家逐步去理解和掌握这些知识;并深入分析源码实现,理解背后的实现原理,知其然还要知其所以然。从多线程核心基础讲起,理解线程的风险,多种创建线程的方式;再到深入理解线程的状态;然后是线程的基本操作。系统、深入、快速上手实现多线程。 课程目标:    快速上手掌握Java多线程的经典课程,    系统、全面、深入掌握Java多线程的核心知识主讲老师:CC老师     20年Java开发和使用经验,多年的首席架构师和CTO,畅销原创书籍《研磨设计模式》的作者。         参与和领导了上百个大中型项目的设计和开发,在互联网应用系统架构、系统设计、    应用级框架和中间件开发等方面具有很多经验和领悟。    更为难得的是,入行20年,仍然奋战在技术一线,深知一线架构师需要掌握哪些技术、    掌握到什么程度、一线架构设计会遇到哪些坑、如何才能做出最合适的架构设计,经验最难得!适应人群:    想要系统、深入学习Java多线程    已有Java开发基础,想要快速掌握Java多线程    补充Java多线程知识,为进入一线大厂做准备学习方式:随到随学课程内容:第一节课:系统理解Java并发编程的知识体系    1:为什么要掌握Java并发编程    2:整个课程的目标    3:整个课程的学习内容第二节课:线程必备基础知识    1:理解线程是什么,理解进程,图示    2:理解轻量级的含义    3:理解时序调度,线程是时序调度的基本单元,图示    4:理解调度方式:抢占式,图示    5:理解我们写的程序基本都是多线程的应用,图示    6:理解并发和并行,图示    7:为什么需要线程第三节课:线程的风险    1:线程安全性问题,图示    2:线程的活跃度问题:死锁、饥饿、活锁,图示    3:线程的性能问题,这里主要是线程间切换 上下文的开销第四节课:创建线程的方式之一    1: 代码演示:实现Runnable接口的方式来创建线程    2:学习Thread类的方法和属性的应用    3:学习Thread类的源码第五节课:创建线程的方式之二    1:继承Thread的方式来创建线程    2:继续学习Thread类的源码,分析线程初始化过程    3: 代码演示:演示ThreadGroup    4: 代码演示:演示daemon线程,理解daemon线程和主线程的关系第六节课:创建线程的方式之三    1: 代码演示:匿名内部类的方式来创建线程    2:继续学习Thread类的源码,分析run方法的调用过程    3:代码演示:callable的方式来创建线程,带返回值    4: 学习FutureTask的部分源码,分析run方法到call方法的调用过程第七节课:线程状态详解    1:通过Thread源码来查看线程状态的定义    2:一步一步画图,讲述状态之间的变迁第八节课:线程的基本操作sleep 和yield    1:阅读Thread源码    2:代码演示:sleep的使用    3:代码演示:yield的使用    4:sleep和yield的对比理解第九节课:线程的基本操作join和interrupt    1:阅读Thread源码    2:代码演示:join的使用    3:代码演示:interrupt的使用这里是《Java并发编程与源码分析》的第一部分——讲述多线程核心基础实现快速上手多线程的经典之作   

1,593

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 网络通信/分布式开发
社区管理员
  • 网络通信/分布式开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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