Windows 多线程整理

本文详细介绍了Windows线程开发的相关知识,包括线程的创建与销毁、同步与通信,并提供了多种创建线程的方法,如CreateThread、_beginthread、_beginthreadex和AfxBeginThread,同时对比了它们之间的区别。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近参加面试,被面试官问到了Windows线程开发相关的问题,完全回答不上来。百度一下很多关于多线程的说明,在此我整理下便于自己以后查找。

主要问题有

1. 线程的创建

2.线程的销毁

3.线程同步,通信

 

第一节 关于线程的创建

可以通过以下几种方法创建一个线程:
1、CreateThread
2、_beginthread
3、_beginthreadex
4、AfxBeginThread

第一种 windows API

HANDLE CreateThread(PL_SECURITY_ATTIBUTE plsa, DWOD cbStack, LP_THREAD_START_ROUTINE lpst, LPVOID lpvThreadParam,  DWOD fdwCreate, LPWORD lpIDThread);

 线程函数定义    DWOD ThreadFunc(LPVOID param);

第二中和第三种

引用头文件:
#include <process.h>

函数原型:
uintptr_t _beginthread( void( *start_address )( void * ),
            unsigned stack_size,
            void *arglist );
参数:
start_address:新线程的起始地址 ,指向新线程调用的函数的起始地址
stack_size:新线程的堆栈大小,可以为0
arglist: 传递给线程的参数列表,无参数是为NULL 
 
返回值:
假如成功,函数将返回一个处理信息对这个新创建的线程。如果失败_beginthread将返回-1。

unsigned long _beginthreadx(void* security, 
                            unsigned stack_size, 
                            unsigned (__stdcall *start_addr)(void*), 
                            void* arglist, 
                            unsigned initFlag, 
                            unsigned* threadAddr);

参数:可参考CreateThread函数的参数
返回值:
与_beginthread()不同的是:_beginthread返回-1表示失败, 而_beginthreadex()返回0表示失败!

第四种,MFC中使用
        在MFC中,用户界面线程和工作者线程都是由AfxBeginThread创建的,MFC提供了两个重载版的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* AfxBeginThread(    AFX_THREADPROC pfnThreadProc,
                  LPVOID lParam,
                  int nPriority = THREAD_PRIORITY_NORMAL,
                  UINT nStackSize = 0,
                  DWORD dwCreateFlags = 0,
                  LPSECURITY_ATTRIBUTES lpSecurityAttrs = NULL
                 );//用于创建工作者线程
参数:
pfnThreadProc : 线程的入口函数,声明一定要如下: UINT MyThreadFunction(LPVOID pParam),不能设置为NULL;
pParam : 传递入线程的参数,注意它的类型为:LPVOID,所以我们可以传递一个结构体入线程.
nPriority : 线程的优先级,一般设置为 0 .让它和主线程具有共同的优先级.
nStackSize : 指定新创建的线程的栈的大小.如果为 0,新创建的线程具有和主线程一样的大小的栈
dwCreateFlags : 指定创建线程以后,线程有怎么样的标志.可以指定两个值:
--------------------------------------------------------------------------------------
CREATE_SUSPENDED : 线程创建以后,会处于挂起状态,直到调用:ResumeThread
0 : 创建线程后就开始运行.
--------------------------------------------------------------------------------------
lpSecurityAttrs : 指向一个 SECURITY_ATTRIBUTES 的结构体,用它来标志新创建线程的安全性.如果为 NULL,
返回值:
一个指向新线程的线程对象的指针


以上几种创建线程的区别


其实windows只提供了一个创建线程的方法,就是CreateThread,后面三个函数都是由CreateThread间接得到。
1、_beginthread和_beginthreadex的区别
首先我们看看这两个函数都干了什么:
uintptr_r __cdecl _beginthreadex(...)
{
    //为即将创建的线程分配一个数据结构_ptiddata ptd(per-thread data)
    //初始化这个数据结构,其中ptd->_thandle = (uintptr_t)(-1)
    //如果初始化失败,返回(uintptr_t)(0) [_beginthread返回-1]
    //用传进来的参数,调用CreateThread
    //如果创建成功返回CreateThread返回的代码
    //如果创建失败则释放ptd,并返回(uintptr_t)(0) [_beginthread返回-1,而CreateThread失败返回0,非-1]
}
然后再看看这两个函数有什么不同
(1)参数列表不同, ex版本的参数和CreateThread差不多:
(2)二者在初始化ptd失败时返回的值不同
(3)_beginthread的参数缺少安全描述符. 而且它是创建线程的时候先以挂起状态创建 (CreateThread会填充ptd->_thandle和ptd->_tid) 然后再ResumeThread。_beginthread是根据传进来的参数创建线程
(4)失败返回值不同,ex版本的与Windows API CreateThread返回值是一直的,这也是提倡使用后者的原因之一
 
2、CreateThread()、_beginthreadex()及、AfxBeginThread()
CreateThread时Windows API接口函数,_beginthreadex函数是C/C++运行库提供的函数,从 _beginthreadex函数的源代码,可以看出它的主要动作是:增加了一个名为ptd的_ptiddata的结构的处理,然后在调用CreateThread函数。_ptiddata是每个线程都拥有自己的专用的数据结构。AfxBeginThread是MFC封装的启动线程的函数,里面包含了很多和MFC相关的启动信息,而且封装了一些常用的操作,使用起来也比较简便。而用另外两个函数就需要程序员对类型,安全性检查进行更多的思考!
 

引用地址 https://blog.youkuaiyun.com/yangshuangtao/article/details/51284140

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值