在进行多线程程序设计的时候,我们经常用到afxbeginthread函数来启动一条线程
该函数使用起来非常的简单方便,其定义如下
cwinthread* afxbeginthread(
afx_threadproc pfnthreadproc,//线程函数地址
lpvoid pparam,//线程参数
int npriority = thread_priority_normal,//线程优先级
uint nstacksize = 0,//线程堆栈大小,默认为1m
dword dwcreateflags = 0,//
lpsecurity_attributes lpsecurityattrs = null
);
cwinthread* afxbeginthread(
cruntimeclass* pthreadclass,
int npriority = thread_priority_normal,
uint nstacksize = 0,
dword dwcreateflags = 0,
lpsecurity_attributes lpsecurityattrs = null
);
参数说明:
pfnthreadproc:线程函数的地址,该参数不能设置为null,线程函数必须定义成全局函数或者类的静态成员函数
例如:
uint mythreadfunc(lpvoid lparam)
或者
class a
{
public:
static uint __stdcall mythreadfunc(lpvoid lparam);
}
之所以要定义成类的静态成员函数,是因为类的静态成员函数不属于某个类对象,这样在调用函数
的时候就不用传递一个额外的this指针.
pthreadclass:指向从cwinthread派生的子类对象的runtime_class
pparam:要传递给线程函数的参数
npriority:要启动的线程的优先级,默认优先级为thread_priority_normal(普通优先级),关于线程
优先级的详细说明请参考platform sdk setthreadpriority函数说明
nstacksize:新线程的堆栈大小,如果设置为0,则使用默认大小,在应用程序中一般情况下线程的默认堆栈大小
为1m
dwcreateflags:线程创建标志,该参数可以指定为下列标志
create_suspended:以挂起方式启动线程,如果你在线程启动之前想初始化一些cwinthread类中的一些成员变量
比如:m_bautodelete或者你的派生类中的成员变量,当初始化完成之后,你可以使用cwinthread类的resumethread
成员函数来恢复线程的运行
如果把该标志设置为0,则表示立即启动线程
lpsecurityattrs:指向安全描述符的指针,如果使用默认的安全级别只要讲该参数设置为null就可以了!
上面就是afxbeginthread函数的简单说明,我们在使用的时候一般情况下只要指定前两个参数,其他
参数使用默认值就可以.嗯,的确,使用起来是很简单,只要这个函数一被调用,就创建了一个线程.
但是大家有没有想过,afxbeginthread函数究竟是如何启动的线程呢?它的内部是如何实现的呢?
下面我们就来看一下afxbeginthread函数的内部实现
//启动worker线程
cwinthread* afxapi afxbeginthread(afx_threadproc pfnthreadproc, lpvoid pparam,
int npriority, uint nstacksize, dword dwcreateflags,
lpsecurity_attributes lpsecurityattrs)
{
#ifndef _mt
pfnthreadproc;
pparam;
npriority;
nstacksize;
dwcreateflags;
lpsecurityattrs;
return null;
#else
assert(pfnthreadproc != null);
cwinthread* pthread = debug_new cwinthread(pfnthreadproc, pparam);
assert_valid(pthread);
if (!pthread->createthread(dwcreateflags|create_suspended, nstacksize,
lpsecurityattrs))
{
pthread->delete();
return null;
}
verify(pthread->setthreadpriority(npriority));
if (!(dwcreateflags & create_suspended))
verify(pthread->resumethread() != (dword)-1);
return pthread;
#endif //!_mt)
}
//启动ui线程
cwinthread* afxapi afxbeginthread(cruntimeclass* pthreadclass,
int npriority, uint nstacksize, dword dwcreateflags,
lpsecurity_attributes lpsecurityattrs)
{
#ifndef _mt
pthreadclass;
npriority;
nstacksize;
dwcreateflags;
lpsecurityattrs;
return null;
#else
assert(pthreadclass != null);
assert(pthreadclass->isderivedfrom(runtime_class(cwinthread)));
cwinthread* pthread = (cwinthread*)pthreadclass->createobject();