Last active
November 11, 2015 18:11
-
-
Save dnikku/ee891049764caecbba9c to your computer and use it in GitHub Desktop.
_beginthreadex/CreateThread leaks when using CRT or not (with multiple wait)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "stdafx.h" | |
/* | |
stdafx.f: | |
#include <time.h> | |
#include <stdio.h> | |
#include <tchar.h> | |
#include <Windows.h> | |
#include <process.h> | |
*/ | |
static volatile LONG g_scheduledThreads = 0; | |
static volatile LONG g_executedThreads = 0; | |
static volatile INT64 g_size = 0; | |
static CRITICAL_SECTION g_cs; | |
static ULONGLONG g_started = GetTickCount64(); | |
int getLogTime() { | |
return (int) ((GetTickCount64() - g_started) / 1000); | |
} | |
void printCounts(int step) { | |
printf(" %03d sec: step:%d, scheduled:%d, completed:%d\n", getLogTime(), step, g_scheduledThreads, g_executedThreads); | |
} | |
void executeThread(int v){ | |
//leaks: | |
time_t tt = _time64(NULL); | |
//leaks: FILETIME ft; GetSystemTimeAsFileTime(&ft); | |
//no leaks: char sz[524 * 1024]; sprintf(sz, "Salutare de la mare"); | |
//no leaks: SYSTEMTIME stm; GetSystemTime(&stm); g_size += stm.wSecond; | |
//EnterCriticalSection(&g_cs); g_executedThreads++; LeaveCriticalSection(&g_cs); | |
InterlockedAdd(&g_executedThreads, 1); | |
} | |
static unsigned int __stdcall _beginthreadex_wrapper(void *arg) { | |
executeThread(1); | |
return 0; | |
} | |
const int maxThreadsCount = MAXIMUM_WAIT_OBJECTS; | |
bool _beginthreadex_factory(int& step) { | |
DWORD lastError = 0; | |
HANDLE threads[maxThreadsCount]; | |
int threadsCount = 0; | |
while (threadsCount < maxThreadsCount){ | |
unsigned int id; | |
threads[threadsCount] = (HANDLE)_beginthreadex(NULL, | |
64 * 1024, _beginthreadex_wrapper, NULL, STACK_SIZE_PARAM_IS_A_RESERVATION, &id); | |
if (threads[threadsCount] == NULL) { | |
lastError = GetLastError(); | |
break; | |
} | |
else threadsCount++; | |
} | |
if (threadsCount > 0) { | |
WaitForMultipleObjects(threadsCount, threads, TRUE, INFINITE); | |
for (int i = 0; i < threadsCount; i++) CloseHandle(threads[i]); | |
} | |
step += threadsCount; | |
g_scheduledThreads += threadsCount; | |
if (threadsCount < maxThreadsCount) { | |
printf(" %03d sec: step:%d, _beginthreadex failed. err(%d); errno(%d). exiting ...\n", getLogTime(), step, lastError, errno); | |
return false; | |
} | |
else return true; | |
} | |
int _tmain(int argc, _TCHAR* argv[]) { | |
printf("starting ...\n"); | |
//InitializeCriticalSection(&g_cs); | |
bool(*f_wrapper) (int&) = _beginthreadex_factory; | |
int loop = 1; | |
while (true) { | |
int step = 0; | |
for (int i = 0; i < 10000; i++) { | |
int j = 0; | |
if (!f_wrapper(step)){ | |
Sleep(5 * 1000); // wait some time ... | |
printf(" sleep 5 seconds\n"); | |
printCounts(step); | |
// try to create 10 more threads | |
printf(" try to create 2 more times\n"); | |
for (j = 1; j < 2; j++) f_wrapper(step); | |
break; // exit from for ... | |
} | |
if (step % 6400 == 0) printCounts(step); // print progress | |
} | |
Sleep(4 * 1000); // wait to stop all threads | |
printCounts(step); | |
printf("rerun loop: %d", loop++); | |
getchar(); // press enter to rerun | |
} | |
return 0; | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment