使用互斥对象:
#include <windows.h>
#include <iostream>
#define THREADCOUNT 6
HANDLE ghMutex;
DWORD WINAPI RunThreadFunction(LPVOID lpParam);
int main(void)
{
HANDLE aThread[THREADCOUNT];
DWORD ThreadID;
// 创建一个无所有者的互斥锁
ghMutex = CreateMutex(
NULL,
FALSE,
NULL);
if (ghMutex == NULL)
{
std::cout << "CreateMutex error: " << GetLastError() << std::endl;
return 1;
}
for(int i = 0; i < THREADCOUNT; i++)
{
aThread[i] = CreateThread(
NULL,
0,
(LPTHREAD_START_ROUTINE) RunThreadFunction,
NULL,
0,
&ThreadID);
if( aThread[i] == nullptr )
{
std::cout << "CreateThread error: " << GetLastError() << std::endl;
return 1;
}
}
// 等到所有线程都终止
WaitForMultipleObjects(THREADCOUNT, aThread, TRUE, INFINITE);
for(int i = 0; i < THREADCOUNT; i++ )
CloseHandle(aThread[i]); // 关闭所有线程句柄并释放内存
CloseHandle(ghMutex);
return 0;
}
DWORD WINAPI RunThreadFunction(LPVOID lpParam)
{
UNREFERENCED_PARAMETER(lpParam);
DWORD dwWaitResult;
for(int i = 0; i < 5; i++)
{
// 获得互斥权
dwWaitResult = WaitForSingleObject(
ghMutex,
INFINITE);
switch (dwWaitResult)
{
case WAIT_OBJECT_0:
try {
std::cout << i << " Thread " << GetCurrentThreadId() << " is run..."<< std::endl;
}
catch (...) {
if (! ReleaseMutex(ghMutex)) // 释放互斥权
{
std::cout << "ReleaseMutex error" << std::endl;
}
}
break;
// 线程处于不确定状态
case WAIT_ABANDONED:
return FALSE;
}
}
return TRUE;
}
如果去掉互斥锁可看到输出十分混乱...原因也在于std::cout的输出是拼接的。如果用printf来输出会好一些,但输出的 i 可能是混乱的。
如下图:

加锁的运行结果:

下面是在MSDN看到的一个创建线程的例子,如果想要传递其他类型的参数且没有类型转换的警告,可以这样做:
#include <windows.h>
#include <tchar.h>
#include <strsafe.h>
#define MAX_THREADS 3
#define BUF_SIZE 255
DWORD WINAPI MyThreadFunction( LPVOID lpParam );
void ErrorHandler(LPTSTR lpszFunction);
typedef struct MyData {
int val1;
int val2;
} MYDATA, *PMYDATA;
int _tmain()
{
PMYDATA pDataArray[MAX_THREADS];
DWORD dwThreadIdArray[MAX_THREADS];
HANDLE hThreadArray[MAX_THREADS];
for( int i=0; i<MAX_THREADS; i++ )
{
pDataArray[i] = (PMYDATA) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(MYDATA));
if( pDataArray[i] == NULL )
{
ExitProcess(2);
}
pDataArray[i]->val1 = i;
pDataArray[i]->val2 = i+100;
hThreadArray[i] = CreateThread(
NULL,
0,
MyThreadFunction,
pDataArray[i],
0,
&dwThreadIdArray[i]);
if (hThreadArray[i] == NULL)
{
ErrorHandler((LPTSTR)TEXT("CreateThread"));
ExitProcess(3);
}
}
WaitForMultipleObjects(MAX_THREADS, hThreadArray, TRUE, INFINITE);
for(int i=0; i<MAX_THREADS; i++)
{
CloseHandle(hThreadArray[i]);
if(pDataArray[i] != NULL)
{
HeapFree(GetProcessHeap(), 0, pDataArray[i]);
pDataArray[i] = NULL;
}
}
return 0;
}
DWORD WINAPI MyThreadFunction( LPVOID lpParam )
{
HANDLE hStdout;
PMYDATA pDataArray;
TCHAR msgBuf[BUF_SIZE];
size_t cchStringSize;
DWORD dwChars;
hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
if( hStdout == INVALID_HANDLE_VALUE )
return 1;
pDataArray = (PMYDATA)lpParam;
StringCchPrintf(msgBuf, BUF_SIZE, TEXT("Parameters = %d, %d\n"), pDataArray->val1, pDataArray->val2);
StringCchLength(msgBuf, BUF_SIZE, &cchStringSize);
WriteConsole(hStdout, msgBuf, (DWORD)cchStringSize, &dwChars, NULL);
return 0;
}
void ErrorHandler(LPTSTR lpszFunction)
{
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 );
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);
LocalFree(lpMsgBuf);
LocalFree(lpDisplayBuf);
}
重点部分就是用到了结构型。