initial checkin
This commit is contained in:
153
ThreadTest/ThreadTest.cpp
Normal file
153
ThreadTest/ThreadTest.cpp
Normal file
@@ -0,0 +1,153 @@
|
||||
#include <windows.h>
|
||||
#include <tchar.h>
|
||||
#include <strsafe.h>
|
||||
|
||||
#define MAX_THREADS 3
|
||||
#define BUF_SIZE 255
|
||||
|
||||
DWORD WINAPI MyThreadFunction(LPVOID lpParam);
|
||||
void ErrorHandler(LPCTSTR lpszFunction);
|
||||
|
||||
// Sample custom data structure for threads to use.
|
||||
// This is passed by void pointer so it can be any data type
|
||||
// that can be passed using a single void pointer (LPVOID).
|
||||
typedef struct MyData {
|
||||
int val1;
|
||||
int val2;
|
||||
} MYDATA, *PMYDATA;
|
||||
|
||||
bool running = true;
|
||||
|
||||
int _tmain() {
|
||||
PMYDATA pDataArray[MAX_THREADS];
|
||||
DWORD dwThreadIdArray[MAX_THREADS];
|
||||
HANDLE hThreadArray[MAX_THREADS];
|
||||
|
||||
// Create MAX_THREADS worker threads.
|
||||
|
||||
for ( int i = 0; i < MAX_THREADS; i++ ) {
|
||||
// Allocate memory for thread data.
|
||||
|
||||
pDataArray[i] = (PMYDATA)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
|
||||
sizeof(MYDATA));
|
||||
|
||||
if ( pDataArray[i] == NULL ) {
|
||||
// If the array allocation fails, the system is out of memory
|
||||
// so there is no point in trying to print an error message.
|
||||
// Just terminate execution.
|
||||
ExitProcess(2);
|
||||
}
|
||||
|
||||
// Generate unique data for each thread to work with.
|
||||
|
||||
pDataArray[i]->val1 = i;
|
||||
pDataArray[i]->val2 = i + 100;
|
||||
|
||||
// Create the thread to begin execution on its own.
|
||||
|
||||
hThreadArray[i] = CreateThread(
|
||||
NULL, // default security attributes
|
||||
0, // use default stack size
|
||||
MyThreadFunction, // thread function name
|
||||
pDataArray[i], // argument to thread function
|
||||
0, // use default creation flags
|
||||
&dwThreadIdArray[i]); // returns the thread identifier
|
||||
|
||||
|
||||
// Check the return value for success.
|
||||
// If CreateThread fails, terminate execution.
|
||||
// This will automatically clean up threads and memory.
|
||||
|
||||
if ( hThreadArray[i] == NULL ) {
|
||||
ErrorHandler(TEXT("CreateThread"));
|
||||
ExitProcess(3);
|
||||
}
|
||||
} // End of main thread creation loop.
|
||||
|
||||
// Wait until all threads have terminated.
|
||||
|
||||
WaitForMultipleObjects(MAX_THREADS, hThreadArray, TRUE, INFINITE);
|
||||
|
||||
// Close all thread handles and free memory allocations.
|
||||
|
||||
for ( int i = 0; i < MAX_THREADS; i++ ) {
|
||||
CloseHandle(hThreadArray[i]);
|
||||
if ( pDataArray[i] != NULL ) {
|
||||
HeapFree(GetProcessHeap(), 0, pDataArray[i]);
|
||||
pDataArray[i] = NULL; // Ensure address is not reused.
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
DWORD WINAPI MyThreadFunction(LPVOID lpParam) {
|
||||
HANDLE hStdout;
|
||||
PMYDATA pDataArray;
|
||||
|
||||
TCHAR msgBuf[BUF_SIZE];
|
||||
size_t cchStringSize;
|
||||
DWORD dwChars;
|
||||
|
||||
// Make sure there is a console to receive output results.
|
||||
|
||||
hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
if ( hStdout == INVALID_HANDLE_VALUE )
|
||||
return 1;
|
||||
|
||||
int counter = 0;
|
||||
while (running) {
|
||||
// Cast the parameter to the correct data type.
|
||||
// The pointer is known to be valid because
|
||||
// it was checked for NULL before the thread was created.
|
||||
|
||||
pDataArray = (PMYDATA)lpParam;
|
||||
|
||||
// Print the parameter values using thread-safe functions.
|
||||
|
||||
StringCchPrintf(msgBuf, BUF_SIZE, TEXT("Parameters = %d, %d, [%d]\n"),
|
||||
pDataArray->val1, pDataArray->val2, counter++);
|
||||
StringCchLength(msgBuf, BUF_SIZE, &cchStringSize);
|
||||
WriteConsole(hStdout, msgBuf, (DWORD)cchStringSize, &dwChars, NULL);
|
||||
Sleep(1000 + 1000 * pDataArray->val1 );
|
||||
if ( counter > 5 )
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void ErrorHandler(LPCTSTR lpszFunction) {
|
||||
// Retrieve the system error message for the last-error code.
|
||||
|
||||
LPVOID lpMsgBuf;
|
||||
LPVOID lpDisplayBuf;
|
||||
DWORD dw = GetLastError();
|
||||
|
||||
FormatMessage(
|
||||
FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
||||
FORMAT_MESSAGE_FROM_SYSTEM |
|
||||
FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||
NULL,
|
||||
dw,
|
||||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
||||
(LPTSTR)&lpMsgBuf,
|
||||
0, NULL);
|
||||
|
||||
// Display the error message.
|
||||
|
||||
lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT,
|
||||
(lstrlen((LPCTSTR)lpMsgBuf) + lstrlen((LPCTSTR)lpszFunction) + 40) * sizeof(TCHAR));
|
||||
StringCchPrintf((LPTSTR)lpDisplayBuf,
|
||||
LocalSize(lpDisplayBuf) / sizeof(TCHAR),
|
||||
TEXT("%s failed with error %d: %s"),
|
||||
lpszFunction, dw, lpMsgBuf);
|
||||
MessageBox(NULL, (LPCTSTR)lpDisplayBuf, TEXT("Error"), MB_OK);
|
||||
|
||||
// Free error-handling buffer allocations.
|
||||
|
||||
LocalFree(lpMsgBuf);
|
||||
LocalFree(lpDisplayBuf);
|
||||
}
|
||||
135
ThreadTest/ThreadTest.vcxproj
Normal file
135
ThreadTest/ThreadTest.vcxproj
Normal file
@@ -0,0 +1,135 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<VCProjectVersion>17.0</VCProjectVersion>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<ProjectGuid>{4bc4f1e9-6288-453c-b752-dc21e331b314}</ProjectGuid>
|
||||
<RootNamespace>ThreadTest</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="ThreadTest.cpp" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
Reference in New Issue
Block a user