这篇文章主要介绍了详解_beginthreadex()创建线程,使用_beginthreadex(),需要的头文件支持#包含过程。h下面我们就来看看具体的实现吧
目录
一、使用_beginthreadex()二、beginthreadex()与代CreateThread()区别
一、使用_beginthreadex()
需要的头文件支持#include //for _beginthread()
需要的设置:Project设置- C/C -用户运行时库选择调试多线程或者多线程。即使用:MT或MTD。
代码如下:
#包含标准视频
#include string //用于标准模板库字符串类
#include windows.h //for HANDLE
#包含流程。h//for _ beginthread()
使用命名空间标准
ThreadX类
{
私人:
内部循环开始
int循环结束
内部位移频率
公共:
字符串线程名称
ThreadX(整数起始值,整数结束值,整数频率)
{
循环开始=开始值
循环结束=结束值
位移频率=频率;
}
静态无符号_ _ stdcall ThreadStaticEntryPoint(void * pt this)
{
ThreadX * pthX=(ThreadX *)pt this;//棘手的演员阵容
pthX-ThreadEntryPoint();//现在调用真正的入口点函数
返回1;//线程退出代码
}
void ThreadEntryPoint()
{
for(int I=loopStart;i=循环结束我)
{
如果(i %显示频率==0)
{
printf( '%s: i=%d\n ',threadName.c_str(),I);
}
}
printf( '%s线程终止\n ',线程名称。c _ str());
}
};
int main()
{
ThreadX * o1=new ThreadX( 0,1,2000);
处理hth1
无符号uiThread1ID
hth 1=(HANDLE)_ beginthreadex(NULL,//security
0,//堆栈大小
ThreadX:ThreadStaticEntryPoint,
o1,//参数列表
创建_挂起,//这样我们以后就可以调用ResumeThread()
ui thread 1 id);
如果(hth1==0)
printf('无法创建线程1 \ n’);
DWORD dwExitCode
GetExitCodeThread( hth1,dwExitCode);//应该是STILL_ACTIVE=0x00000103=259
printf('初始线程一退出代码=%u\n ',dwExitCode);
O1-threadName=' t1 ';
ThreadX * o2=new ThreadX( -100000,0,2000);
处理hth2
无符号uiThread2ID
hth 2=(HANDLE)_ beginthreadex(NULL,//security
0,//堆栈大小
ThreadX:ThreadStaticEntryPoint,
o2,//参数列表
创建_挂起,//这样我们以后就可以调用ResumeThread()
ui thread 2 id);
如果(hth2==0)
printf('无法创建线程2 \ n’);
GetExitCodeThread( hth2,dwExitCode);//应该是STILL_ACTIVE=0x00000103=259
printf('初始线程2退出代码=%u\n ',dwExitCode);
O2-threadName=' T2 ';
ResumeThread(hth 1);//服务于耶西克的t1-开始()的目的
ResumeThread(hth 2);
WaitForSingleObject( hth1,INFINITE);
WaitForSingleObject( hth2,INFINITE);
GetExitCodeThread( hth1,dwExitCode);
printf('线程一退出,代码为%u\n ',dwExitCode);
GetExitCodeThread( hth2,dwExitCode);
printf('线程2退出,代码为%u\n ',dwExitCode);
关闭手柄(hth 1);
关闭手柄(hth 2);
删除O1;
o1=空
删除O2;
o2=空;
printf('主线程正在终止. \ n ');
返回0;
}
注意:
(1)如果是写C/C代码,千万不要调用CreateThread。相反,应该使用VisualC运行时库函数_beginthreadex,退出也应该使用_endthreadex。如果你不使用微软的VisualC编译器,你的编译器厂商有自己的CreateThread替换函数。无论这个替代函数是什么,你都必须使用它。(2)因为_beginthreadex和_endthreadex是CRT线程函数,所以一定要注意编译选项runtimelibaray的选择,使用MT或者MTD。[多线程,调试多线程].(3)beginthreadex函数的参数列表与CreateThread函数的参数列表相同,但参数名称和类型不完全相同。这是因为微软的C/C运行时库的开发团队认为,C/C运行时函数不应该对Windows数据类型有任何依赖。_beginthreadex函数和CreateThread一样,返回新创建线程的句柄。(4)C主线程的终止也会终止主线程创建的所有子线程,不管子线程是否已经执行完毕。因此,如果在上面的代码中没有调用WaitForSingleObject,两个子线程t1和t2可能不会完全执行或者根本不会执行。(5)如果一个线程挂起,然后有一个WaitForSingleObject的调用等待线程,就会导致死锁。所以上面的代码如果不调用resumethread,就会死锁。
二、_beginthreadex()与代CreateThread()区别
CreateThread是Windows的API函数(SDK函数的标准形式,直截了当的创建方法,可以在任何场合使用),提供操作系统级别的创建线程的操作,仅限工作线程。不调用MFC和RTL的函数时,可以使用CreateThread,不要轻易做其他的事情。在使用过程中,要考虑进程的同步和互斥的关系(防止死锁)。函数定义为:dword winapi _ yourthreadfun(lpvoid PP parameter)。但是它不考虑:
(1)多线程需要在1)C运行时进行记录和初始化,以保证C函数库的正常工作(典型的例子就是strtok函数)。(2)MFC还需要知道新线程的创建,做一些初始化工作(当然不用MFC也行)。
AfxBeginThread:MFC程序创建的MFC函数先创建对应的CWinThread对象,然后调用CWinThread:CreateThread,在其中完成了Thread对象的初始化,然后调用_beginthreadex(AfxBeginThread比AFX安全)创建线程。它简化了操作或使线程能够响应消息,这可用于接口线程和工作线程,但注意不要在MFC程序中使用_beginthreadex()或CreateThread()。线程函数定义为:UINT
_yourThreadFun(LPVOID pParam)
_beginthreadex:MS扩展coruntime库的SDK功能。首先,为coruntime库做了一些初始化工作,以确保coruntime库正常工作。然后,调用CreateThread来实际创建线程。仅使用运行时库时,可以使用_BegingThread。
小节:其实这三个函数之间有一定的调用关系。第一个是纯的,后两个完成相应的工作后,调用前者创建线程。CreateThread是操作系统提供的接口,AfxBeginThread和_BeginThread是编译器的包。小节:_beginthreadex()和_endthreadex函数应该是最好的选择,它们都是C运行库中的函数。函数的参数和数据类型都是C运行库中的类型,所以启动线程时不需要将Windows数据类型转换为C运行库中的数据类型,减少了启动线程时的资源消耗和时间消耗。但是,使用_beginthread,您不能创建一个具有安全属性的新线程,创建一个挂起的线程,或者获取线程ID。_endthread的情况也类似。它不带参数,这意味着这个线程的退出代码必须硬编码为0。小节:MFC也是C类库(只是微软的C类库,不是标准的C类库)。在MFC中,它还封装了new和delete的操作符,所以在使用new和delete的地方没有必要使用_beginthreadex()函数。您可以使用其他两个函数。
_beginthreadex和_beginthread在回调入口函数之前执行一些线程相关的CRT初始化操作。
CRT的函数库在线程出现之前就已经存在,所以原来的CRT并不能真正支持线程,
这也导致了很多CRT函数在多线程的情况下必须有特殊的支持,单纯使用CreateThread是不行的。
补充一点:_beginthreadex()是用于CRT的线程函数。如果要在线程中使用CRT的函数,最好用这个启动线程。如果不用这个,会有内存泄露。
关于_beginthreadex()线程创建的这篇文章到此为止。有关_beginthreadex()线程创建的更多信息,请搜索我们以前的文章或继续浏览下面的相关文章。希望你以后能支持我们!
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。