The following is a sample use of _beginthreadex. In this sample, an event is
created and passed as an argument. The thread checks the event in a loop and
when the event is signaled (by the main thread) the thread returns. Please read
the _beginthreadex() and _endthreadex() documentation; this sample assumes you
have and that you are familiar with it.
#if !defined(_MT)
#error _beginthreadex requires a multithreaded C run-time library.
#endif
#define STRICT 1
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <process.h>
#include <iostream>
using namespace std;
#define Second (1000)
unsigned __stdcall Thread(void *ArgList) {
HANDLE hEvent = *((HANDLE*)ArgList);
while (WaitForSingleObject(hEvent, 0) != WAIT_OBJECT_0) {
Sleep(Second>>2); // sleep for a quarter of a second
cout << "Waiting for signal\n";
}
cout << "Thread ending\n";
return 0;
}
int main(int argc, char *argv[], char *envp[]) {
int ErrorNumber, DOSErrorNumber;
unsigned ThreadId;
HANDLE hThread, hEvent;
// Create a manual-reset nonsignaled unnamed event
hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
hThread = (HANDLE)_beginthreadex(NULL, 0, Thread, &hEvent, 0, &ThreadId);
if (hThread == 0) {
ErrorNumber = errno;
DOSErrorNumber = _doserrno;
cerr << "Begin thread error: " << strerror(ErrorNumber) << '\n';
cerr << "Begin thread DOS error code: " << DOSErrorNumber << '\n';
return 16;
}
cout << "Thread begun\n";
Sleep(Second<<1); // wait 2 seconds
SetEvent(hEvent); // signal thread to end
int rv = WaitForSingleObject(hThread, Second<<3); // wait up to 8 seconds
cout << "Thread wait rv " << rv << '\n';
CloseHandle(hEvent);
CloseHandle(hThread);
return 0;
}
Microsoft Knowledge Base article 132078 ("How to Use _beginthreadex() and
_endthreadex()")
The KB article 132078 ("How to Use _beginthreadex() and _endthreadex()")
seems to have been archived, so I will summarize here what it says. It
essentially says that it is better to use _beginthreadex() and _endthreadex()
and it has a sample program. My sample above is an improved version of the
sample in the KB article.
Use of the Win32 APIs CreateThread() and EndThread() directly is incompatible
with the C Runtime (CRT) Library. In particular, use of CreateThread() and
EndThread() directly can cause loss of memory that the CRT allocates.
Instead, we must use either _beginthread() and _endthread() or _beginthreadex()
and _endthreadex().
The advantage of _beginthreadex() compared to _beginthread() is that _beginthreadex()
provides more control and is safer. For example, with _beginthreadex(), you can:
- use security information
- create the thread suspended initially
- get the thread identifier of the thread
- use the thread handle after the thread completes, allowing use of the the
synchronization APIs (as above) for the thread
The advantage of _endthreadex() compared to _endthread() is that _endthreadex()
is more flexible.