说是多线程库,其实就是一个单独的.h文件,可以方便的放入WTL/win32工程中。
下载地址:CThread. 里面也简单介绍了 用法。
具体用法,首先自定义一个子线程类继承CThreadImpl<T>,注意他是个模板类。
class CMySubThread:public CThreadImpl<CMySubThread>
然后,在类中定义需要的成员变量,比如,一般都要有一个窗口句柄,这个窗口就是你这个子线程要和哪个窗口进行交互,或者子线程的执行结果要返回给哪个窗口。
重写父类的Run方法,子线程启动后,就执行这个Run方法。
简单起见,我的子线程类定义如下:
#pragma once
class CMySubThread:public CThreadImpl<CMySubThread>
{
public:CMySubThread();DWORD Run();DWORD i;HWND m_hWnd;};
类实现也比较简单:
#include "stdafx.h"
#include "MySubThread.h"CMySubThread::CMySubThread()
{i = 0;m_hWnd = NULL;
}DWORD CMySubThread::Run()
{int i = 0;while (!IsAborted()) {::Sleep(2000);::PostMessage(m_hWnd, WM_THREAD, WPARAM(i++), NULL); }return 0;
}
说一下Run方法:是一个循环,只要没在外部调用子线程的Stop方法,子线程就一直运行。循环里就是把自增变量 i 通过win32自定义消息的方式发送给窗口。一旦在外部什么地方调用子线程的Stop()方法,循环就退出了,子线程执行结束。
在类的外部,比如在主窗口(对话框)类CMainDlg中(由于我用的是WTL库,主窗口类名叫这个),定义一个子线程对象
CMySubThread m_thread;
在合适的地方把m_thread对象的窗口句柄变量赋值为主窗口句柄,然后在合适的地方启动子线程:
m_thread.m_hWnd = m_hWnd;
m_thread.Start();
这样,子线程就运行起来了。
注意事项:
1、可以只定义一个子线程对象,然后多次调用Start()方法,运行多个子线程。
2、多个子线程中的变量数据是单独的,有自己的地址空间,不干扰。按上面的例子说,就是启动两个子线程的话,变量i 都是从0开始,各自自增。
3、重点1:如果子线程是个死循环,或非常耗时的操作,比如Run方法这样:
DWORD CMySubThread::Run()
{int i = 0;while (true) {::Sleep(2000);::PostMessage(m_hWnd, WM_THREAD, WPARAM(i++), NULL); }return 0;
}
这种情况下,调用子线程的Stop()方法是无法结束子线程的,主线程也会卡在Stop()这里,一直等子线程结束。所以不推荐子线程写个死循环,一般写成
while (!IsAborted())
4、重点2:写成这样还有个好处,就是当启动多个子线程时,可以在窗口结束前调用一次Stop,这样所有的子线程都退出结束了。