V513. Use _beginthreadex/_endthreadex functions instead of CreateThread/ExitThread functions

22.02.2011

A use of the CreateThread function or ExitThread function is detected in a program. If CRT (C run-time library) functions are used in concurrent threads, you should call the functions _beginthreadex/_endthreadex instead of CreateThread/ExitThread.

Below is an extract from the 6-th chapter of the book "Advanced Windows: creating efficient Win32-applications considering the specifics of the 64-bit Windows" by Jeffrey Richter / 4-th issue.

CreateThread is a Windows-function creating a thread. But never call it if you write your code in C/C++. You should use the function _beginthreadex from the Visual C++ library instead.

To make multi-threaded applications using C/C++ (CRT) library work correctly, you should create a special data structure and link it to every thread from which the library functions are called. Moreover, they must know that when you address them, they must look through this data block in the master thread in order not to damage data in some other thread.

So how does the system know that it must create this data block together with creating a new thread? The answer is very simple - it doesn't know and never will like to. Only you are fully responsible for it. If you use functions which are unsafe in multi-threaded environment, you should create threads with the library function _beginthreadex and not Windows-function CreateThread.

Note that the _beginthreadex function exists only in multi-threaded versions of the C/C++ library. When linking a project to a single-threaded library, the linker will generate an error message "unresolved external symbol". Of course, it is done intentionally since the single-threaded library cannot work correctly in a multi-threaded application. Note also that Visual Studio chooses the single-threaded library by default when creating a new project. This way is not the safest one, so you should choose yourself one of the multi-threaded versions of the C/C++ library for multi-threaded applications.

Correspondingly, you must use the function _endthreadex to destruct a thread created with the function _beginthreadex.

Additional materials on this topic:

You can look at examples of errors from real projects which were detected by this diagnostic message.