创建线程有三种方式,分别时CreateThread、AfxBeginThread、_beginthreadex
目录
创建线程有三种方式,分别时CreateThread、AfxBeginThread、_beginthreadex
一、三者的区别:
1、CreateThread。CreateThread是Windows提供的系统API任何时候都可以使用。
2、AfxBeginThread。AfxBeginThread是MFC对CreateThread的封装。AfxBeginThread会返回一个CWinThread的指针,也就是说他会New一个CWinThread型对象。而这个对象会自己维护线程句柄和ID,不再需要手动回收线程句柄。MFC实际开发过程中,使用CreateThread创建的线程总是会出现莫名其妙的Bug,尽量使用AfxBeginThread。
3、_beginThreadex。是C++运行库对CreateThread的封装,因为C++ 运行库里面有一些函数使用了全局变量,如果使用CreateThread的情况下使用这些C++ 运行库的函数,就会出现不安全 的问题。而 _beginthreadex 为这些全局变量做了处理,使得每个线程都有一份独立 的“全局”量。尽量使用_beginthreadex()来代替使用CreateThread()
二、相关函数
函数名称 | 函数功能 |
CreateThread | 创建新线程 |
AfxBeginThread | 创建新线程 |
_beginthreadex | 创建新线程 |
ExitThread | 结束本线程的执行 |
TerminateThead | 强制终止任意一个线程 |
ResumeThread | 恢复一个线程 |
SuspendThread |
挂起一个线程 |
GetExiCodeThread | 得到一个线程的推出码 |
GetThreadPriority | 得到一个线程的优先级 |
SetThreadPriority | 设置一个线程的优先级 |
CloseHandle | 关闭一个线程句柄 |
CreateRemoteThread | 在一个线程中创建一个新的线程 |
PostThreadMessage | 发送一条消息给指定的线程 |
GetCurrentThread | 得到当前线程句柄 |
GetCurrentThreadId | 得到当前的线程ID |
GetThreadId | 得到指定线程的ID |
WaitForSingleObject | 等待一个对象 |
WaitForMultipleObjects | 等待多个线程对象 |
GetLastError | 获取错误代码 |
其中部分函数不常用,不再介绍有需要的话请百度
2.1 CreateThread
原型:HANDLE CreateThread(
LPSECURITY_ATTRIBUTES secAttr,
SIZE_T stackSize,
LPTHREAD_START_ROUTINE threadFunc,
LPVOID param,
DWORD flags,
LPDWORD threadID
);
功能:创建新的线程
参数:
secAttr 描述线程内核对象安全属性指针。为NULL时会使用默认的安全描述符。一般使用NULL
stackSize 线程栈控件大小。如果为0那么线程堆栈大小与创建它的线程相同。
threadFunc 线程函数地址。线程函数的原型必须是DWORD WINAPI Thread1(LPVOID param);WINAPI是一个宏,所表示的符号为__stdcall
param 是传给线程函数Thread1的参数,如果不需要可以为NULL,但是实际使用时很少为NULL
flags 标志线程执行状态,0表示线程创建后立刻执行,CREATE_SUSPENDED表示线程创建后立刻挂起。直到调用ResumeThread
threadid 线程ID。如果为NULL则表示不需要线程ID。一般为NULL
返回值:成功返回线程句柄,失败返回NULL
2.2 CloseThread
原型:BOOL CloseHandle( HANDLE hObject );
功能:释放线程句柄(并不是线程结束),程序退出之前必须释放句柄不然会引起内存泄漏
参数:
hObject 一个已经打开的对象句柄。
返回值:成功返回TRUE,失败返回FLASE
2.3 SuspendThread
原型:DWORD WINAPI SuspendThread(HANDLE hThread);
功能:挂起指定的线程
参数:
hThread 线程句柄
返回值: -1(0xFFFFFFFF)表示失败,否则返回线程被挂起的次数
2.4 ResumeThread
功能:使线程挂起次数减一,线程挂起次数为0时线程才会继续运行
参数:
hThread 线程句柄
返回值: -1(0xFFFFFFFF)表示失败,否则返回线程被挂起的次数
2.5 ExitThread
原型:VOID ExitThread(DWORD dwExitCode);
功能:终止本线程的运行,并导致操作系统清除该线程使用的所有操作系统资源。但C++资源(如对象)将不会被撤销,所以最好由线程函数自己返回,特别时是哦那个C++时。
参数:
dwExitCode 线程退出时的返回值
2.6 TerminateThead
原型:BOOL WINAPI TerminateThread( HANDLE hThread,DWORD dwExitCode );
功能:强行终止一个线程。该函数为异步的,即改函数返回时并不能保证线程已退出。使用该函数终止线程时,线程并不知道,所以无法执行任何用户级代码会导致一些问题。如:1)如果目标线程拥有关键字段,那么关键字段不会被释放,这可能会引起资源泄漏和死锁。2)如果线程在堆上申请了内存,那么该内存不会被释放,这将会引起内存泄漏。3)如果目标线程正在操作一个共享的DLL,那么DLL的状态可能会被破坏,从而影响其他的使用者或者导致未知错误。
参数:
hThread 线程句柄
dwExitCode 线程退出时的返回值
返回值:成功返回真,失败返回假
2.7 WaitForSingleObject
原型:DWORD WaitForSingleObject(HANDLE hObject,DWORD dwMilliseconds);
功能:等待内核对象为已通知状态
参数:
hObject 要等待的内核对象句柄,可以时线程句柄
dwMilliseconds 超时时间。单位ms。当为INFINITE时表示一直等下去直到内核对象为通知状态。
返回值:WAIT_OBJECT_0 内核对象在超时时间内为已通知状态,WAIT_TIMEOUT内核对象在超时时间内未变成已通知状态,WAIT_FAILED函数调用失败。
2.8 WaitForMulitpleObjects
原型:DWORD WaitForMultipleObjects(
DWORD dwCount,
CONST HANDLE* phObjects,
BOOL bWaitAll,
DWORD dwMilliseconds);
功能:等待多个内核对象变为已通知状态
参数:
dwCount 等待的内核对象个数,范围:0-64
phObjects 等待的内核对象组成的数组
bWaitAll TRUE表示所有内核对象为已通知状态时函数才返回,FLASE表示只要有一个内核对象为已通知状态时函数就返回
dwMilliseconds 超时时间。单位ms。当为INFINITE时表示一直等下去直到内核对象为通知状态。
返回值:WAIT_OBJECT_0 内核对象在超时时间内为已通知状态,WAIT_TIMEOUT内核对象在超时时间内未变成已通知状态,WAIT_FAILED函数调用失败。当bWaitAll为FLASE时返回WAIT_OBJECT_0 + n表示phObjects[n – 1]句柄为已通知状态。
2.9 AfxBeginThread
AfxBeginThread可以创建工作者线程和用户界面线程。区别在于用户界面线程有消息循环和消息处理函数可以处理消息响应而工作者线程没有
创建用户界面线程的原型:CWinThread* AFXAPI AfxBeginThread(
CRuntimeClass* pThreadClass,
int nPriority,
UINT nStackSize,
DWORD dwCreateFlags,
LPSECURITY_ATTRIBUTES lpSecurityAttrs)
参数:
pThreadClass 从CWinThread派生的RUNTIME_CLASS类
nPriority 线程优先级。如果为0表示与创建该线程的线程相同
nStackSize 指定线程的栈大小。如果为0表示与创建该线程的线程相同
dwCreateFlags 创建标识。如果是CREATE_SUSPENDED,则在悬挂状态创建线程,在线程创建后线程挂起,否则线程在创建后开始线程的执行。
lpSecurityAttrs 安全属性,NT下有用
创建工作者线程原型:CWinThread* AFXAPI AfxBeginThread(
AFX_THREADPROC pfnThreadProc,
LPVOID pParam,
int nPriority,
UINT nStackSize,
DWORD dwCreateFlags,
LPSECURITY_ATTRIBUTES lpSecurityAttrs)
参数:
pfnThreadProc 线程函数。函数声明格式如下:UINT MyThreadFunction( LPVOID pParam );
pParam 传入线程MyThreadFunction的参数
nPriority 线程优先级。如果为0表示与创建该线程的线程相同
nStackSize 指定线程的栈大小。如果为0表示与创建该线程的线程相同
dwCreateFlags 创建标识。如果是CREATE_SUSPENDED,则在悬挂状态创建线程,在线程创建后线程挂起,否则线程在创建后开始线程的执行。
lpSecurityAttrs 安全属性,NT下有用
返回值:AfxBeginThread的返回值是CWinThread型对象,不是线程句柄。线程句柄为CWinThread型对象的公有属性m_hThread。
2.10 _beginthreadex
原型:unsigned long _beginthreadex( void *security,
unsigned stack_size,
unsigned ( __stdcall *start_address )( void * ),
void *arglist,
unsigned initflag, unsigned *thrdaddr );
参数:
security 线程安全属性,NULL表示默认安全属性。一般为NULL
stack_size 线程堆栈大小,如果为0则堆栈大小和创建它的线程一样。一般为0
start_address 线程函数
arglist 传递给线程的参数
thrdaddr 标志线程执行状态,0表示线程创建后立刻执行,CREATE_SUSPENDED表示线程创建后立刻挂起。直到调用ResumeThread
thrdaddr 线程ID,不需要时可以为NULL
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/38460.html