关于线程的停止和挂起
来源:互联网 发布:淘宝买家怎么改价格 编辑:程序博客网 时间:2024/05/21 10:41
在用线程的时候经常要启动和挂起,原来d7的时候可以用resume和suspend(但是,建议不要用这2个方法,因为这2个方法在操作系统层面会造成死锁),现在版本的TThread里已经把这2个方法声明为deprecated(我用的是xe2,具体不知道从哪个版本起)。原来在D7的时候要挂起线程,也没用suspend,也是自己实现。
参考置顶帖(现在好象没了,只有推荐了,见 http://bbs.csdn.net/topics/360046056 ),主要是参考它的退出线程方法,写了个"通用"线程。
注:实际也不通用,我的情况是通用于主从方式的数据采集,某些系统资源,比如串口什么的,数据采集线程和主线程共用,也就是一般情况下,数据采集线程通过串口循环不断采集下位机的数据,当需要时,主线程可以挂起数据采集线程,让出资源(串口)供主线程用。
数据采集线程中,资源(串口)占用时候时间有长有短,长的时候可能数秒,主线程发出挂起命令后,采集线程不一定马上结束工作,因而要判断采集线程是否真正完成了"工作",主线程是否可以用资源(串口)了,这里就有一个等待采集线程工作完成的问题。
代码用起来虽然没发现有什么问题,不过感觉有点别扭,等待以后改进了
unit unHardWorkThread;interfaceuses Winapi.Windows, Winapi.Messages, System.Classes, System.SysUtils, System.SyncObjs, unGeneral;const WM_QUIT_HARD_THREAD = WM_USER + 301; DELAY_TIME_MIN = 10;type THardWorkThread = class(TThread) private FQuitEvent:TEvent; //退出线程 FSuspendEvent:TEvent; //挂起线程事件,有信号表示正在工作,无信号表示已经挂起 FWorkEvent:TEvent; //正在工作事件 FPIsInterrupt:PBoolean; //中断 FDelayTime:Word; //延迟 FIsWorking:Boolean; //是否工作中 protected SupervisorCtl:TObject; //管理者对象 MsgHandle:THandle; //消息目的窗口句柄 ErrorCount:Integer; //连续错误次数 procedure Execute; override; procedure DoWorkProc(const APIsInterrupt:PBoolean); virtual; abstract; //实际的工作过程(虚方法,子类必须实现) public constructor Create(ASupervisorCtl:TObject; AMsgHandle:THandle; ADelayTime:Word); destructor Destroy; override; function ExitThread(const AWaitTime:Integer):Boolean; //退出线程 function SuspendThread(const AWaitTime:Integer):Boolean; //挂起线程 function ResumeThread(const AWaitTime:Integer):Boolean; //恢复线程 function WaitForWorkCompleted(const AWaitTime:Integer):Boolean; //等待线程工作完成 end;implementation{ THardWorkThread }constructor THardWorkThread.Create(ASupervisorCtl: TObject; AMsgHandle: THandle; ADelayTime:Word);begin inherited Create(True); SupervisorCtl:=ASupervisorCtl; MsgHandle:=AMsgHandle; FQuitEvent:=TEvent.Create; FSuspendEvent:=TEvent.Create; FWorkEvent:=TEvent.Create; New(FPIsInterrupt); FPIsInterrupt^:=False; FIsWorking:=False; ErrorCount:=0; FDelayTime:=ADelayTime;end;destructor THardWorkThread.Destroy;begin Dispose(FPIsInterrupt); FWorkEvent.Free; FSuspendEvent.Free; FQuitEvent.Free; inherited;end;{procedure THardWorkThread.DoWorkProc;beginend;}procedure THardWorkThread.Execute;var Msg:TMsg;begin FreeOnTerminate:=True; while True do begin if PeekMessage(Msg,0,0,0,PM_REMOVE) then begin if Msg.message = WM_QUIT_HARD_THREAD then begin FQuitEvent.SetEvent; Break; end; end; if FPIsInterrupt^ then begin Continue; end; FSuspendEvent.WaitFor(INFINITE); if FPIsInterrupt^ then begin Continue; end; FIsWorking:=True; FWorkEvent.ResetEvent; try DoWorkProc(FPIsInterrupt); finally FWorkEvent.SetEvent; FIsWorking:=False; end; if FDelayTime > DELAY_TIME_MIN then begin if DelayCanInterrupt(FDelayTime,FPIsInterrupt) then Continue; end; end;end;function THardWorkThread.ExitThread(const AWaitTime: Integer): Boolean;begin Result:=True; PostThreadMessage(ThreadID,WM_QUIT_HARD_THREAD,0,0); FPIsInterrupt^:=True; if FQuitEvent.WaitFor(AWaitTime) = wrTimeOut then Result:=False;end;function THardWorkThread.ResumeThread(const AWaitTime: Integer): Boolean;begin FSuspendEvent.SetEvent; Result:=True;end;function THardWorkThread.SuspendThread(const AWaitTime: Integer): Boolean;const Def_WaitTime = 10;begin Result:=False; if FSuspendEvent.WaitFor(Def_WaitTime) = wrSignaled then begin if WaitForWorkCompleted(AWaitTime) then begin FSuspendEvent.ResetEvent; Result:=True; end; end else begin FSuspendEvent.ResetEvent; Result:=True; end;end;function THardWorkThread.WaitForWorkCompleted(const AWaitTime: Integer): Boolean;begin if FIsWorking then Result:=FWorkEvent.WaitFor(AWaitTime) = wrSignaled else Result:=True;end;end.
这里用了workevent,isworking,suspendevent,感觉有点乱,暂时还不清楚怎么简化。
- 关于线程的停止和挂起
- 关于线程的停止、挂起、退出(修改)
- 【JAVA】挂起、恢复和停止线程的示例代码
- 线程的挂起和恢复
- 线程的挂起和访问
- 线程的挂起和唤醒
- 线程的挂起和唤醒
- 关于停止线程和唤起线程的方法
- 关于线程的停止问题
- Linux下线程的挂起和恢复
- 线程的挂起,唤醒和终止
- CPrcThread<Worker>线程的挂起和恢复
- Android : 线程的结束,挂起和恢复
- java 线程的挂起和唤醒
- MFC线程的挂起、唤醒和终止
- Android 线程的结束,挂起和恢复
- Android: 线程的结束,挂起和恢复
- Linux下线程的挂起和恢复
- stored to '*' during its initialization is never read
- NoSQL非关系数据库简介
- CSS中怎么让DIV居中
- 现有分布式技术(socket、.net remoting、asp.net webservice、WSE、ES)和wcf的比较及优势
- Android 常用的距离单位
- 关于线程的停止和挂起
- NSDate 整理笔记
- SQL语句中查找条目中包含某一字符串的方法
- jQuery实现文件下载( 隐藏表单实现ajax下载 )
- webkit内核几篇学习的文章
- Aix6.1安装WebSphere(版本: 7.0.0.19)
- linux getopt函数 分析命令行参数
- bash: /usr/bin/yum: /usr/bin/python: bad interpreter: No such file or direct
- 程序人生之我们的故事:十年如歌(1)