Windows multi-thread threads create one. Thread creation function CreateThread1. Function prototypes
HANDLE WINAPI CreateThread( _In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes, _In_ SIZE_T dwStackSize, _In_ LPTHREAD_START_ROUTINE lpStartAddress, _In_opt_ LPVOID lpParameter, _In_ DWORD dwCreationFlags, _Out_opt_ LPDWORD lpThreadId );
2, parameter description
The first parameter, Lpthreadattributes, represents the security attribute of the thread kernel object, and a general pass-through of NULL means the default setting is used.
The second parameter, Dwstacksize, represents the size of the line stacks space. Passing 0 means using the default size (1MB).
The third parameter, lpstartaddress, represents the address of the thread function that the new thread executes, and multiple threads can use the same function address.
The fourth parameter, Lpparameter, is a parameter passed to the thread function.
The fifth parameter, dwCreationFlags, specifies an additional flag to control the creation of the thread, 0 indicates that the thread is dispatched immediately after it is created, and if creaate_suspended indicates that the thread was created and paused, it cannot be dispatched until the ResumeThread ().
The sixth parameter, Lpthreadid, returns the ID number of the thread, and passing in NULL means that it does not need to return the thread's ID number.
3. Return value
? The thread creation successfully returned a new thread handle and failed to return NULL.
4. Sample Code
#include <windows.h>#include <stdio.h>DWORD WINAPI ThreadFunc(LPVOID);int main(){ HANDLE hThread; DWORD threadID; printf("Enter the main thread ...\n"); hThread = CreateThread(NULL, 0, ThreadFunc, 0, 0, NULL); for (int i = 0; i < 2; i++) { printf("I am the main thread,PID = %d\n", GetCurrentThreadId()); Sleep(1000); } printf("Quit the main thread ...\n"); return 0;}DWORD WINAPI ThreadFunc(LPVOID){ printf("Enter the child thread ...\n"); for (int i = 0; i < 2; i++) { printf("I am child thread,PID = %d\n", GetCurrentThreadId()); Sleep(500); } printf("Quit the child thread ...\n"); return 0;}
The results of the implementation are as follows:
Two. Thread creation function _beginthreadex () 1. Overview
? The CreateThread () function is a Windows-provided API interface that has another function _beginthreadex () that creates threads in the C + + language, and we should try to use _beginthreadex () instead of Createthrea D () because it is more secure than CreateThread.
? The reason is to start with the standard C run-time library and multi-threaded contradiction, the standard C run-time library was implemented in 1970, because there is no one operating system to provide multi-threaded support. Therefore, programmers writing the standard C Runtime library do not consider the use of the standard C Runtime library for multithreaded applications. such as the global variable errno of the standard C Runtime library. Many functions in the runtime copy the error code to this global variable in case of an error, which makes it easy to debug. But if there is a code snippet like this:
if (system("notepad.exe readme.txt") == -1) { switch(errno) { ...//错误处理代码 }
? Assuming that a thread a executes the above code, and that thread has not called the switch () statement after calling system (), another thread B starts, and this thread B also invokes the function of the standard C run-time library, unfortunately this function performs an error and writes the error code to the global variable errno. This way, when thread a starts executing the switch () statement, it accesses a errno that has been modified by the B thread. This situation must be avoided! Because not only is this variable problematic, other functions such as strerror (), Strtok (), Tmpname (), Gmtime (), and Asctime () can also encounter data coverage problems that have been caused by multiple thread access modifications.
? To solve this problem, the Windows operating system provides a solution-each thread will have its own dedicated chunk of memory to provide all the required functions in the standard C run-point library. and the creation of this area of memory is the responsibility of _beginthreadex (), the C + + Runtime library function. The _beginthreadex () function allocates and initializes a _tiddata block when a new thread is created. This _tiddata block is naturally used to store some data that needs to be held exclusively by threads. When the new thread runs, it first associates the _tiddata block with itself. The new thread then calls the standard C run-time library function, such as strtok (), and then takes the address of the _tiddata block and then the data that needs to be protected into the _tiddata block. This way each thread will only be able to access and modify its own data without tampering with other threads ' data. Therefore, if you have a function in your code that uses the standard C run-time library, use _beginthreadex () instead of createthread () whenever possible.
2. Function prototypes
unsigned long _beginthreadex(void* security, unsigned stack_size, unsigned(_stdcall *start_address)(void*), void* arglist, unsigned initflag, unsigned* thrdaddr );
3. Parameter description
The first parameter, security, represents a safety property, and NULL is the default security attribute.
The second parameter, stack_size, specifies the size of the thread stack. If 0, the thread stack size is the same as the thread that created it. General use 0.
The third parameter, start_address, specifies the address of the thread function, which is the function address that the thread invokes to execute (with the function name, the function name represents the address).
The fourth parameter, arglist, represents a pointer to a parameter passed to the thread, which can then be converted into a pointer to the corresponding class by passing in a pointer to the object.
The fifth parameter, Initflag, represents the thread initialization state, 0 means running immediately; Create_suspend is a suspension.
The sixth parameter, THRDADDR, is used to record the address of a thread ID.
4. Return value
? The thread creation successfully returned a new thread handle and failed to return NULL.
5. Sample Code
#include <Windows.h>#include <process.h>#include <stdio.h>unsigned int _stdcall ThreadFunc(PVOID pParam){ printf("the child thread %d: Hello world!\n", GetCurrentThreadId()); return 0;}int main(){ const int THREAD_MUN = 5; HANDLE handles[THREAD_MUN]; for (int i = 0; i < THREAD_MUN; i++) { handles[i] = (HANDLE)_beginthreadex(NULL, 0, ThreadFunc, NULL, 0, NULL); } WaitForMultipleObjects(THREAD_MUN, handles, TRUE, INFINITE); return 0;}
The results of the implementation are as follows:
01 Creating Threads CreateThread and _beginthreadex