Windows多线程编程详解

创建线程有三种方式,分别时CreateThread、AfxBeginThread、_beginthreadex

 目录

创建线程有三种方式,分别时CreateThread、AfxBeginThread、_beginthreadex

一、三者的区别:

二、相关函数

2.1 CreateThread

2.2 CloseThread

2.3 SuspendThread

2.4 ResumeThread

2.5 ExitThread

2.6 TerminateThead

2.7 WaitForSingleObject

2.8 WaitForMulitpleObjects

2.9 AfxBeginThread

2.10 _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


  • 4
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zxz520zmg

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值