beginthreadex()
一、createthread和beginthread的区别
CreateThread、_beginthread和_beginthreadex都是用来启动
线程的,但大家看到oldworm没有提供_beginthread的方式,考试,大提示beginthread是_beginthreadex的功能子
集,虽然_beginthread内部是调用_beginthreadex但他屏蔽了象安全特性这样的功能,所以_beginthread与
CreateThread不是同等级别,_beginthreadex和CreateThread在功能上完全可替代,我们就来比较一下
_beginthreadex与CreateThread!
CRT的函数库在线程出现之前就已经存在,所以原有的CRT不能真正支持线程,这
导致我们在编程的时候有了CRT库的选择,在MSDN中查阅CRT的函数时都有:
Libraries
LIBC.LIB
Single thread static library, retail version
LIBCMT.LIB
Multithread static library, retail version
MSVCRT.LIB Imp
ort
library for MSVCRT.DLL, retail version
这样的提示!
对于线程的支持是后来
的事!
这也导致了许多CRT的函数在多线程的情况下必须有特殊的支持,不能简单的使用CreateThread就OK。
大多的
CRT函数都可以在CreateThread线程中使用,看资料说只有signal()函数不可以,会导致进程终止!但可以用并不是说没有问题!
有些CRT的函数象malloc(), fopen(), _open(), strtok(), ctime(),
或localtime()等函数需要专门的线程局部存储的数据块,这个数据块通常需要在创建线程的时候就建立,如果使用CreateThread,这个
数据块就没有建立,然后会怎样呢?在这样的线程中还是可以使用这些函数而且没有出错,实际上函数发现这个数据块的指针为空时,会自己建立一个,然后将其与
线程联系在一起,这意味着如果你用CreateThread来创建线程,然后使用这样的函数,会有一块内存在不知不觉中创建,遗憾的是,这些函数并不将其
删除,而CreateThread和ExitThread也无法知道这件事,于是就会有Memory
Leak,在线程频繁启动的软件中(比如某些服务器软件),迟早会让系统的内存资源耗尽!
_beginthreadex(内部也调用
CreateThread)和_endthreadex就对这个内存块做了处理,所以没有问题!(不会有人故意用CreateThread创建然后用
_endthreadex终止吧,而且线程的终止最好不要显式的调用终止函数,自然退出最好!)
谈到Handle的问
题,_beginthread的对应函数_endthread自动的调用了CloseHandle,而_beginthreadex的对应函数
_endthreadex则没有,所以CloseHandle无论如何都是要调用的不过_endthread可以帮你执行自己不必写,其他两种就需要自己
写!(Jeffrey Richter强烈推荐尽量不用显式的终止函数,用自然退出的方式,自然退出当然就一定要自己写CloseHandle)。
二、c++link.exe出错
学习VC++时经常会遇到链接错误LNK2001,而一般说来发生连接错误时,编译都已通过。产生连接错误的原因非常多,尤其LNK2001错误,常常使人不明其所以然。产生LNK2001错误的原因:一个是由于编码错误导致的LNK2001,在这不想详细说.另一个由于编译和链接的设置而造成的 LNK2001.最经常发生的是:"LIBCD.lib(wincrt0.obj): error LNK2001: unresolved external symbol",产生这个错误的原因是没有为wWinMainCRTStartup设定程序入口.认识这个错误首先在新建工程时要分清Win32 Application和Win32 Console Application.它们都是工作在32位Windows环境的程序.其中Win32 Application就是普通的常见的窗口应用程序,当然有的界面做得比较个性化,比如圆形的、不规则形状的.它们都是所谓的GUI(Graphics User Interface图形用户接口),我们可以通过鼠标点击来完成控制。而Win32 Console Application(win32控制台应用程序)往往是像MS-DOS窗口(XP中叫命令提示符)的样子出现,我们得用键盘输入各种命令来使用它,或者叫CUI(Character User Interface字符用户接口)。
遇到如下链接错误:
Linking.../subsystem:windows
LIBCD.lib(wincrt0.obj): error LNK2001: unresolved external symbol _WinMain@16
Debug/TestWin.exe: fatal error LNK1120: 1 unresolved externals
Error executing link.exe.
解决方法是:将project-settings-link的project options里的/subsystem:windows
改成/subsystem:console因为Win32 Application的入口函数为WinMain
Win32 Console Application的入口函数是main也就是说,如果你编写传统的C程序,必须建立Win32 Console程序,但VC里面默认的是Win32 Application,于是上面提及的链接错误就就经常出现了
而Win32 Application和Win32 Console的区别就在于VC里链接参数不同另外几种error LNK2001错误:在创建MFC项目时,不使用MFC AppWizard向导,如果没有设置好项目参数,就会在编译时产生很多连接错误,如error LNK2001错误,典型的错误提示有:
libcmtd.lib(crt0.obj): error LNK2001: unresolved external symbol _main
LIBCD.lib(wincrt0.obj): error LNK2001: unresolved external symbol _WinMain@16
msvcrtd.lib(crtexew.obj): error LNK2001: unresolved external symbol _WinMain@16
nafxcwd.lib(thrdcore.obj): error LNK2001: unresolved external symbol __beginthreadex
nafxcwd.lib(thrdcore.obj): error LNK2001: unresolved external symbol __endthreadex
下面介绍解决的方法:
1. Windows子系统设置错误,提示:
libcmtd.lib(crt0.obj): error LNK2001: unresolved external symbol _main
Windows项目要使用Windows子系统,而不是Console,可以这样设置:
[Project]--> [Settings]-->选择"Link"属性页,
在Project Options中将/subsystem:console改成/subsystem:windows
2. Console子系统设置错误,提示:
LIBCD.lib(wincrt0.obj): error LNK2001: unresolved external symbol _WinMain@16
控制台项目要使用Console子系统,而不是Windows,设置:
[Project]--> [Settings]-->选择"Link"属性页,
在Project Options中将/subsystem:windows改成/subsystem:console
3.程序入口设置错误,提示:
msvcrtd.lib(crtexew.obj): error LNK2001: unresolved external symbol _WinMain@16
通常, MFC项目的程序入口函数是WinMain,如果编译项目的Unicode版本,程序入口必须改为wWinMainCRTStartup,所以需要重新设置程序入口:
[Project]--> [Settings]-->选择"C/C++"属性页,
在Category中选择Output,
再在Entry-point symbol中填入wWinMainCRTStartup,即可
4.线程运行时库设置错误,提示:
nafxcwd.lib(thrdcore.obj): error LNK2001: unresolved external symbol __beginthreadex
nafxcwd.lib(thrdcore.obj): error LNK2001: unresolved external symbol __endthreadex
这是因为MFC要使用多线程时库,需要更改设置:
[Project]--> [Settings]-->选择"C/C++"属性页,
在Category中选择Code Generation,
再在Use run-time library中选择Debug Multithreaded或者multithreaded
其中,
Single-Threaded单线程静态链接库(release版本)
Multithreaded多线程静态链接库(release版本)
multithreaded DLL多线程动态链接库(release版本)
Debug Single-Threaded单线程静态链接库(debug版本)
Debug Multithreaded多线程静态链接库(debug版本)
Debug Multithreaded DLL多线程动态链接库(debug版本)
单线程:不需要多线程调用时,多用在DOS环境下
多线程:可以并发运行
静态库:直接将库与程序Link,可以脱离MFC库运行
动态库:需要相应的DLL动态库,程序才能运行
release版本:正式发布时使用
debug版本:调试阶段使用