一个小型但有效的关于线程的讨论 - CxThread类!






3.54/5 (22投票s)
2003年3月15日
4分钟阅读

100636

674
关于线程、线程的工作方式以及技巧和窍门的简短而有效的讨论!另外还有一个很酷的实现!
引言
每个人一生中都会有必须处理循环的时候!假设你想让用户选择一个文件夹,然后你开始扫描其中的文件。这可能是一个耗时的过程,用户不想看到应用程序界面卡住。在搜索过程中,他应该能够停止搜索。这是一个我们需要多线程或智慧的问题。
这就是智慧的体现:有人问如何在工作时继续处理应用程序的消息。这是一个相当简单的任务。对于那些使用过 Visual Basic 的人来说,都知道DoEvents()
函数的救命作用。好吧,这就是它在 C/C++ 中的实现!
智慧:DoEvents()
BOOL DoEvents() { MSG msg; while (PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE) == TRUE) { if (GetMessage(&msg, NULL, 0, 0) ) { /*before you translate and dispatch you might consider checking if that message does not close you window you should ignore it because if you doevents() in a loop and the user click the close buton it closes ! and you loop continues untill it ends .*/ if((msg.message!=WM_DESTROY)&&(msg.message!=WM_CLOSE)&& ((msg.message!=WM_SYSCOMMAND)&&(msg.wParam!=SC_CLOSE))) { TranslateMessage(&msg); DispatchMessage(&msg); /*for closing prevention !*/ } } else { /*if all messages in queue processed we can return to our time consuming operation*/ return TRUE; } } return 0; }
以及多线程的方式
什么是线程!技术上来说,微软是这样说的:
线程基本上是程序中的一条执行路径。它也是 Win32 调度的最小执行单元。一个线程由一个堆栈、CPU 寄存器的状态以及系统调度程序的执行列表中的一个条目组成。每个线程共享所有进程的资源。一个进程由一个或多个线程以及程序在内存中的代码、数据和其他资源组成。典型的程序资源包括打开的文件、信号量和动态分配的内存。当系统调度程序赋予其一个线程执行控制权时,程序就开始执行。调度程序确定哪些线程应该运行以及何时运行。优先级较低的线程可能必须等待优先级较高的线程完成其任务。在多处理器机器上,调度程序可以将单个线程移动到不同的处理器以“平衡”CPU 负载。进程中的每个线程都独立运行。除非您使它们相互可见,否则线程将单独执行,并且不知道进程中的其他线程。然而,共享公共资源的线程必须使用信号量或其他进程间通信方法来协调它们的工作。
我说:
想象一下,一个程序就像一栋房子,通常只有一个房间——主线程。在这个房间里,你可以有你的起居室。如果你想洗澡,或者一天辛苦工作后筋疲力尽,你需要一个浴室。在回家的路上,你想象着自己泡在热水里放松。你计划好后,把车停在房子前面,然后带着幸福的傻笑走进屋里,只有一个目的:深陷水中。你叫你的妻子:“亲爱的,我回来了!”,没有回应!你更高兴了,心想:“她走了!我要自己放松一下!”带着轻松的心情,你走进房间,拿了一条毛巾。你脱掉衣服,把毛巾裹在身上。你走进厨房,拿了一个杯子,倒了一些酒,然后一边唱着歌一边走向最终目的地。你打开门,你震惊了!:“我的天哪,女人。你在这里干什么?!?”
这就是线程的真正含义,你得出了建造另一个浴室(线程)的最糟糕的结论,这样即使有人在那个特定时刻正在洗澡(运行),你也可以洗澡(执行)。但是等等,我们的故事并没有这样结束。妻子说:要不要一起?现在我们的男人充满了智慧,并使用了第一种消息窥视技术。他和妻子一起在第一个线程中运行,并且仍然处理来自外部的所有消息!
while(kids_not_home)
{
take_hot_bath(wife_included);
}
这就是我想与你们分享的我的线程类
// Thread.h: interface for the CXThread class. // ////////////////////////////////////////////////////////////////////// #if !defined( AFX_THREAD_H__BC1E1A60_2C98_4D0F_BA79_C1156C9BFFC3__INCLUDED_) #define AFX_THREAD_H__BC1E1A60_2C98_4D0F_BA79_C1156C9BFFC3__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 #include <windows.h> class CXThread { public: unsigned long GetRunTime(); /*The time in miliseconds sience the thread was started - NOT THE CLASS CREATED*/ unsigned long GetExitCode(); /*This returns the number the thread returns when it exits ! make sure it's not still running by using IsOver()*/ bool IsOver(); /*IS the thread terminated*/ bool IsRunning(); /*IS the thread still running*/ bool Terminate(unsigned long exitCode=0); /*force thread to close issueing the exitCode as exit code*/ bool Suspend(); /*suspend thread execution - put thread to sleep CAUTION : THREADS CAN'T WAKE UP BY THEMSELVES ! ONCE YOU PUT A THREAD TO SLEEP IT CAN'T ISSUE A Resume() BY THEMSELVES*/ bool Resume(); /*continue execution for sleeping threads*/ bool Initiate(bool bSuspended=0); /*this is the actual function that does the thread starting if suspended is true the thread is launched suspended waiting for the wake up call*/ CXThread(); virtual ~CXThread(); protected: /*this are overridable functions */ virtual void ExitInstance(); /*this event occures when the thread is over , by it's own or helped : what do I mean ? it ends normally ir it is killed - variable deletion*/ virtual void InitInstance(); /*this event occures before the thread starts it's running - variable initialisation*/ virtual unsigned long ThreadFunction(); /*this is the actual thread body , you override with your class*/ private: /*do not modify this in any way*/ static unsigned long __stdcall Watcher(void * lpVoid); static unsigned long __stdcall ThreadBody(void * lpVoid); HANDLE hTh,hwTh; unsigned long wthID,thID,thsTime,theTime; }; #endif //!defined(AFX_THREAD_H__BC1E1A60_2C98_4D0F_BA79_C1156C9BFFC3__INCLUDED_)
它非常简单!现在我想你想要某种例子!继续阅读。
示例
如何使用每个函数
#include "xthread.h" class CDirSearch : public CDialog,CXThread { protected: /**/ unsigned long ThreadFunction(); void ExitInstance(); void InitInstance(); /**/ //the .cpp body part unsigned long CDirSearch::ThreadFunction() { ListDirectory(dir,"*.*",subdirs); return 1; } void CDirSearch::ExitInstance() { m_OK.EnableWindow(1); } void CDirSearch::InitInstance() { m_OK.EnableWindow(0); }
历史
- 仅在 2003 年 3 月 15 日下午 3:47 发布(我想)
最后但并非最不重要的一点
如果你不明白任何东西,看看代码。你不会错过的。你肯定会明白的!:~) 只需查看源代码,它就会向你凡人的眼睛揭示其最黑暗的秘密。我还告诉你我的另一个小秘密。如果源代码的复杂性让你不知所措,你可以使用非常古老但早已被遗忘的复制粘贴技术。如果你需要更多信息,请查看软件工程师的圣经——被禁止的 MSDN。在其肮脏而布满灰尘的页面中,你会发现许多智慧之言。要了解我们存在、人类、宇宙和外星人的真相,请给我发邮件 tomkat@rol.ro