Header File
process.h
Category
Process Control Routines
Prototype
unsigned long _beginthreadex(void *__security_attr, unsigned __stksize, unsigned (__stdcall *__start)(void *), void *__arg, unsigned __create_flags, unsigned *__thread_id);
Description
Creates a thread and allows specifying the other parameters of the OS API CreateThread (such as security and thread creation flags). The _endthreadex function will be called automatically when the thread function terminates. The value returned from your thread function will be passed along to _endthreadex, which in turn will pass it along to the ExitThread API. The return value can then be retrieved using the GetExitCodeThread API.
Unlike _endthread, the _endthreadex function does not close the thread handle, thereby allowing other threads to block on this one without fear that the handle will be freed out from under the system.
Other than the order of parameters and the closing of the thread handle, _beginthreadex performs same operation as _beginthreadNT.
_beginthreadex returns the handle of the new thread. The return value is a standard Windows handle that can be used in operating system API's such as SuspendThread and ResumeThread.
If unsuccessful, 0 is returned, and errno is set as follows:
EAGAIN |
Too many threads |
ENOMEM |
Not enough memory |
EINVAL |
Bad stack value (i.e. less than 16 bytes or equal to zero) |
Also see the description of the Win32 API GetLastError, in the MSDN Library.
Example
//* Use the -tWM (32-bit multi-threaded target) command-line switch for this example */ #pragma checkoption -tWM #include <windows.h> #include <process.h> #include <stdio.h> #define NTHREADS 25 /* This function acts as the 'main' function for each new thread */ static unsigned __stdcall threadMain(void *arg) { printf("Thread %2d has an ID of %u\n", (int)arg, GetCurrentThreadId()); return 0; } int main(void) { HANDLE hThreads[NTHREADS]; int i; unsigned threadId; SECURITY_ATTRIBUTES sa = { sizeof(SECURITY_ATTRIBUTES), /* structure size */ 0, /* No security descriptor */ TRUE /* Thread handle is inheritable */ }; /* Create NTHREADS inheritable threads that are initially suspended and that will run starting at threadMain()*/ for(i = 0; i < NTHREADS; i++) { hThreads[i] = (HANDLE)_beginthreadex( &sa, /* Thread security */ 4096, /* Thread stack size */ threadMain, /* Thread starting address */ (void *)i, /* Thread start argument */ CREATE_SUSPENDED, /* Create in suspended state */ &threadId); /* Thread ID */ if(hThreads[i] == INVALID_HANDLE_VALUE) { MessageBox(0, "Thread Creation Failed", "Error", MB_OK); return 1; } printf("Created thread %2d with an ID of %u\n", i, threadId); } printf("\nPress ENTER to thaw all threads\n\n"); getchar(); /* Resume the suspended threads */ for(i = 0; i < NTHREADS; i++) ResumeThread(hThreads[i]); /* Wait for the threads to run */ WaitForMultipleObjects(NTHREADS, hThreads, TRUE, INFINITE); /* Close all of the thread handles */ for(i = 0; i < NTHREADS; i++) CloseHandle(hThreads[i]); return 0; }
Portability
POSIX |
Win32 |
ANSI C |
ANSI C++ |
|
+ |
|
|
Copyright(C) 2009 Embarcadero Technologies, Inc. All Rights Reserved.
|
What do you think about this topic? Send feedback!
|