HANDLE CreateThread(lpsa, cbStack, lpStartAddr, lpvThreadParm, fdwCreate, lpIDThread) | |||||
LPSECURITY_ATTRIBUTES lpsa; | /* optional security attributes | */ | |||
DWORD cbStack; | /* initial thread stack size | */ | |||
LPTHREAD_START_ROUTINE lpStartAddr; | /* starting address of thread | */ | |||
LPVOID lpvThreadParm; | /* argument for new thread | */ | |||
DWORD fdwCreate; | /* creation flags | */ | |||
LPDWORD lpIDThread; | /* returned thread ID | */ |
The CreateThread function creates a thread to execute within the address space of the calling process.
lpsa
Points to a SECURITY_ATTRIBUTES data structure that specifies the security attributes for the thread.
The SECURITY_ATTRIBUTES structure has the following format:
typedef struct _SECURITY_ATTRIBUTES { /* sa */
DWORD nLength;
LPVOID lpSecurityDescriptor;
BOOL bInheritHandle;
} SECURITY_ATTRIBUTES;
If lpsa is NULL, the thread is created without a security descriptor, and the resulting handle cannot be inherited.
cbStack
Specifies the size of the stack for the new thread (in bytes). If this parameter is zero, the new thread will have a stack that is the same size as the stack for the first thread in the process.
lpStartAddr
Points to the application-supplied function and represents the starting address of the thread. The function should accept a single 32-bit argument and return a 32-bit exit code.
lpvThreadParm
Specifies a single 32-bit parameter passed to the thread.
fdwCreate
Specifies additional flags that control the creation of the thread. This parameter can have one of the following values:
Value | Meaning |
0 | ||
The thread runs immediately after creation. | ||
CREATE_SUSPENDED | ||
The thread is created in a suspended state, and will not run until the creating thread calls the ResumeThread function. |
lpIDThread
Points to the variable that receives the thread identifier.
If the function is successful, the return value is a handle to the new thread.
If the function fails, the return value is 0. Use the GetLastError function to obtain extended error information.
The thread begins executing at the address specified by the lpStartAddr parameter. If the thread returns from this procedure, then the DWORD return value is used to terminate the thread using the ExitThread function.
The CreateThread function may succeed even if lpStartAddr points to data, code, or is not accessible. If the start address is invalid when the thread runs, an exception will occur, and the thread will terminate. This behavior is similar to the asynchronous nature of CreateProcess, where the process is created even if it refers to bad or missing DLLs. Termination due to a bad start address is handled as an error exit for the new process.
The thread remains in the system until it has terminated and all handles to the thread have been closed through a call to CloseHandle.
When a thread terminates, it attains a state of signaled, satisfying all waits on the object.
If a security descriptor is not provided, the new thread handle has full access to the new thread, and may be used in any function that requires a handle to a thread object.
If a security descriptor is provided, the handle will have access based on an access check against the caller's context. If the access check denies access, the handle will not have access to the thread.
In addition to the STANDARD_RIGHTS_REQUIRED access flags, the following object type specific access flags are valid for thread objects:
Value | Meaning |
THREAD_QUERY_INFORMATION | This access is required to read certain information from the thread object. |
THREAD_SET_INFORMATION | This access is required to set certain information in the thread object. |
SYNCHRONIZE | Synchronization (wait) access. |
THREAD_GET_CONTEXT | This access is required to read the context of a thread using GetThreadContext. |
THREAD_SET_CONTEXT | This access is required to write the context of a thread using SetThreadContext. |
THREAD_SUSPEND_RESUME | This access is required to suspend or resume a thread using SuspendThread or ResumeThread. |
THREAD_ALL_ACCESS | This set of access flags specifies all of the possible access flags for a thread object. This includes CREATE_SUSPENDED; the thread will be created suspended. |
These object specific access flags are used when duplicating the thread handle via DuplicateHandle.
ExitProcess, ExitThread, CreateThread, and a process that is starting (as the result of a CreateProcess call) are serialized between each other within a process. Only one of these events can happen in an address space at a time. This means that:
During process startup and DLL initialization routines, new threads may be created, but they will not begin execution until DLL initialization is done for the process.
Only one thread in a process may be in a DLL initialization or detach routine at a time.
ExitProcess will block until no threads are in their DLL initialization or detach routines.
CloseHandle, CreateProcess, CreateThread, ExitProcess, ExitThread