Timer 是每隔一段时间执行一次 OnTimer 事件, 这个事件在主线程里执行的。
OnIdle 与 OnTimer 类似,也是在主线程里执行的,但是这个事件是尽可能快的产生,而不是每隔一段时间产生的。
这个事件实际上可以理解为程序问你“我可以休息了吗”,如果你在 OnIdle 的参数回答 true, 程序(主线程)就挂起,直到产生下一个事件为止;如果回答了 false, 这个事件结束之后,还会产生这个这个 OnIdle 事件,除非回答了 false 或者产生了其它事件。如果产生了其它的事件,程序就执行了产生的事件,然后再产生 OnIdle 事件。
Thread (线程) 和别的事件都不一样,也不是事件,而是一个函数,一个独立运行的函数,和程序里面其他函数同时执行的函数。
每个程序开始执行的时候,都有一个线程──主线程,所有的事件和函数都在一个线程里面的。打开主程序 (和工程文件同名的 .cpp 文件),所有的事件和函数都是在 WinMain 函数里面调用的,其中 Application->Run(); 这个函数里面是个循环,处理程序里面所有的事件。这个函数发现主窗口关闭,或者收到程序退出的消息,函数返回,程序结束。当 WinMain 函数结束的时候,整个程序就结束了。
在同一个线程里面的任何两个函数或事件,都不能同时执行,只能是当一个事件或函数结束之后,执行另一个事件或函数,或者在是个事件或函数里面调用另一个事件或函数,执行调用的函数或事件时,调用者等待函数结束再继续执行。如果在事件里面长时间循环,系统就无法执行其他操作的事件,只有等这个事件结束才能执行其他事件,如果还想让程序不停止其他事件的反应,就需要调用 Application->ProcessMessages() 函数,这个函数实际上是查看是否有新的事件产生,如果有,就调用新的事件执行,等那个事件结束,继续执行下一条语句。
如果再产生一个线程,无论是用 C 语言函数 _beginthread() 还是用 TThread 类,都会让指定的函数(线程)独立于主程序(主线程)执行,互不干扰,不会互相打断。MSDN 和 BCB 的帮助里面都不提倡用 API 函数启动一个线程,建议用 C 语言函数或者 C++ 线程类。
因为线程是一个独立运行的函数,所以里面可以做一个“死循环”,不停的运行,不会影响主程序。一般需要在这个循环里面判断程序是否结束,如果程序结束,函数就返回,只要函数返回(执行结束),这个线程就结束了。
线程里面一般都这样的 while(程序不结束) { 执行内容; }
--------------------next---------------------
如果你决定使用 OnIdle,那么尽可能多的占用 CPU 资源。因为他问你是否休息你回答的都是“否”,整个程序接近 100% 的CPU资源
OnIdle 里面不能有延时,会影响产生别的事件;OnIdle 里面也不能有长时间的循环,也会影响产生别的事件,会影响整个系统的反应速度。
如果用线程,为了节省 CPU 资源,里面都利用 Sleep 或者 WaitForSingleObject / WaitForMultipleObjects 函数延时或等待,否则也会尽可能的占用 CPU 资源,整个程序接近 100%
如果线程里面用了 Sleep, 就和 Timer 类似了,不如用 Timer 了,没什么实际意义,也变成了每隔一段事件执行一次。
如果要增强效能,线程里面需要用 WaitFor...Object 函数等待某个 Event 的产生,而这个等待不依赖于主程序(线程)。
游戏里面一般都使用的 OnIdle 事件进行显示和执行其他的动作,而一般的应用程序考虑节省资源,都采用 Timer 或线程。
--------------------next---------------------
由于线程是独立运行的,如果在线程里面处理主线程应该处理的内容,例如输出显示结果,会与主线程冲突,
因为很可能由主线程和你创建的线程同时执行一个动作,系统不知道应该怎么做好了。
如果有与主线程冲突的动作,例如修改编辑框或 Memo 的内容,或者是利用 Canvas 显示出图形或文字
① 需要挂起线程等待主线程空闲时在继续执行,并且这个执行的过程中必须保证主线程不做任何的操作,即所谓的同步 (Synchronize). 在 TThread 类里面有这个 Synchronize 方法。这种方法和不是多线程的程序差不多,甚至反应速度还有慢很多,慢在两个线程互相等待上,如果经常这么等待,就不如不用线程了,偶尔的还可以。
② 把需要主线程执行的动作放在一个缓存里面,然后给主线程发送一个消息(PostMessage())告诉主线程有需要处理的内容,然后继续执行,主线程收到这个消息,就可以放心执行这个消息的内容了。这么做的好处是程序反应速度快,缺点是如果动作复杂,那个缓存可能会不好做。
--------------------next---------------------
TThread 相对复杂一些,也会提供更多的功能。
需要从 TThread 类 继承一个子类,在这个子类里面必须有一个 Execute 方法。
//.h
class TMyThread : public TThread
{
public:
__fastcall TMyThread(bool CreateSuspended);
protected:
void __fastcall Execute(void);
};
//.cpp
__fastcall TMyThread::TMyThread(bool CreateSuspended)
: TThread(CreateSuspended)
{
}
void __fastcall TMyThread::Execute(void)
{
//这个函数就是线程的内容, 下面是典型的循环语句
while(!Terminated) //Terminated 为 TThread 的一个属性, 是这个线程结束的标志
{
//执行内容
}
}
//启动这个线程的方法
//①
TMyThread *mythread = new TMyThread(false); //创建一个线程,并且这个线程开始执行
//②
TMyThread *mythread = new TMyThread(true); //创建一个线程,但暂时不执行这个线程函数
SecondProcess->Priority = tpLower; //调节线程的优先级为 Lower
SecondProcess->Resume(); //启动这个线程,Execute 方法开始执行
线程何时结束?
当 Execute 方法结束了,线程就结束了
线程类何时销毁?
如果线程的 FreeOnTerminate 属性为 true, 线程当 Execute 方法结束时自动销毁。
如果线程的 FreeOnTerminate 属性为 false, 线程需要用 delete 销毁。
--------------------next---------------------
阅读(1465) | 评论(0) | 转发(0) |