线程同步解决
不同线程函数的执行顺序,进行线程协调。
API
DWORD WINAPI WaitForSingleObject(
HANDLE hHandle, // 对象句柄 Thread/Event/Job/Mutex/Process/Semaphore/Waitable timer/Memory resource notification
DWORD dwMilliseconds // 等待时间,INFINITE一直等待
);
返回值
WAIT_TIMEOUT 0x00000102L // 等待超时
WAIT_OBJECT_0 0x00000000L // 等待到了指定对象发出信号状态
WAIT_ABANDONED 0x00000080L // 当 hHandle 为 mutex 时,拥有mutex的线程在结束时没有释放内核对象会返回该值。
WAIT_FAILED ((DWORD)0xFFFFFFFF). // 调用GetLastError获得错误信息
DWORD WINAPI WaitForMultipleObjects(
DWORD nCount, // 等待线程数量(最多MAXIMUM_WAIT_OBJECTS个)
const HANDLE* lpHandles, // 线程句柄指针数组(包含多个线程句柄)
BOOL bWaitAll, // 是否全部等待,TRUE,若所有线程都为已通知状态则函数返回 WAIT_OBJECT_0
// FALSE 返回值为线程内核对象数组的索引值
DWORD dwMilliseconds // 等待时间
);
返回值
WAIT_OBJECT_0 to (WAIT_OBJECT_0 + nCount– 1)
WAIT_ABANDONED_0 to (WAIT_ABANDONED_0 + nCount– 1)
WAIT_TIMEOUT 0x00000102L
WAIT_FAILED ((DWORD)0xFFFFFFFF) // 失败 调用GetLastError返回错误信息
例程1:等待子线程执行完毕
#include
#include
#include
DWORD WINAPI ThreadProFunc(LPVOID lpParam);
int main(int argc, char **argv)
{
HANDLE hThread;
DWORD dwThreadId;
hThread = CreateThread( NULL // 默认安全属性
, NULL // 默认堆栈大小
, ThreadProFunc // 线程入口地址
, NULL //传递给线程函数的参数
, 0 // 指定线程立即运行
, &dwThreadId //线程ID号
);
WaitForSingleObject(hThread, INFINITE); // 等待线程执行完毕
CloseHandle(hThread); //关闭线程句柄
for(int i = 0; i < 4; i++) {
printf("nihao\n");
}
system("pause");
return 0;
}
DWORD WINAPI ThreadProFunc(LPVOID lpParam)
{
for(int i = 0; i < 4; i++) {
printf("hello\n");
}
return 0;
}
运行结果
hello
hello
hello
hello
nihao
nihao
nihao
nihao
请按任意键继续. . .
例程2:线程A给变量赋值,线程B取变量的值,主线程打印,对变量值顺序进行控制
#include
#include
#include
int g_iVarA = 10;
int g_iVarB = 30;
int g_iVarC = 0;
HANDLE g_hThreadA;
HANDLE g_hThreadB;
DWORD WINAPI ThreadProFuncA(LPVOID lpParam);
DWORD WINAPI ThreadProFuncB(LPVOID lpParam);
int main(int argc, char **argv)
{
DWORD dwThreadIdA;
DWORD dwThreadIdB;
g_hThreadA = CreateThread( NULL // 默认安全属性
, NULL // 默认堆栈大小
, ThreadProFuncA // 线程入口地址
, NULL //传递给线程函数的参数
, 0 // 指定线程立即运行
, &dwThreadIdA //线程ID号
);
g_hThreadB = CreateThread( NULL , NULL, ThreadProFuncB, NULL, 0, &dwThreadIdB);
WaitForSingleObject(g_hThreadB, INFINITE);
CloseHandle(g_hThreadA); //关闭线程句柄
CloseHandle(g_hThreadB); //关闭线程句柄
printf("g_iVarC = %d\n", g_iVarC);
system("pause");
return 0;
}
DWORD WINAPI ThreadProFuncA(LPVOID lpParam)
{
g_iVarA = 100;
g_iVarB = 200;
return 0;
}
DWORD WINAPI ThreadProFuncB(LPVOID lpParam)
{
WaitForSingleObject(g_hThreadA, INFINITE);
g_iVarC = g_iVarA + g_iVarB;
return 0;
}
例程3:多个线程一起等待操作,返回已经结束线程的最小索引
#include
#include
#include
HANDLE g_hThread[4];
DWORD WINAPI ThreadProFuncA(LPVOID lpParam);
DWORD WINAPI ThreadProFuncB(LPVOID lpParam);
DWORD WINAPI ThreadProFuncC(LPVOID lpParam);
DWORD WINAPI ThreadProFuncD(LPVOID lpParam);
int main(int argc, char **argv)
{
DWORD dwThreadIdA;
DWORD dwThreadIdB;
DWORD dwThreadIdC;
DWORD dwThreadIdD;
g_hThread[0] = CreateThread( NULL, NULL, ThreadProFuncB, NULL, 0, &dwThreadIdB);
g_hThread[2] = CreateThread( NULL, NULL, ThreadProFuncC, NULL, 0, &dwThreadIdC);
g_hThread[3] = CreateThread( NULL, NULL, ThreadProFuncD, NULL, 0, &dwThreadIdD);
g_hThread[1] = CreateThread( NULL // 默认安全属性
, NULL // 默认堆栈大小
, ThreadProFuncA // 线程入口地址
, NULL //传递给线程函数的参数
, 0 // 指定线程立即运行
, &dwThreadIdA //线程ID号
);
DWORD retErr = WaitForMultipleObjects(4, g_hThread, false, INFINITE);
CloseHandle(g_hThread[0]); //关闭线程句柄
CloseHandle(g_hThread[1]); //关闭线程句柄
CloseHandle(g_hThread[2]); //关闭线程句柄
CloseHandle(g_hThread[3]); //关闭线程句柄
printf("main, retErr = %x\n", retErr); // 正常,返回最小的结束线程的索引号
system("pause");
return 0;
}
DWORD WINAPI ThreadProFuncA(LPVOID lpParam)
{
printf("A");
return 0;
}
DWORD WINAPI ThreadProFuncB(LPVOID lpParam)
{
WaitForSingleObject(g_hThread[1], INFINITE);
Sleep(2000);
printf("B");
return 0;
}
DWORD WINAPI ThreadProFuncC(LPVOID lpParam)
{
Sleep(2000);
printf("C\n");
return 0;
}
DWORD WINAPI ThreadProFuncD(LPVOID lpParam)
{
printf("D\n");
return 0;
}
运行结果:
D
main, retErr = 3
A请按任意键继续. . . BC