#include "stdafx.h" #include <windows.h> #include <process.h> int g_count; const int ThreadNum = 10; unsigned int __stdcall Func(LPVOID pm) { int id = *(int*)pm; Sleep(10); g_count++; printf_s("id=%d,count=%d ", id, g_count); return 0; } int main() { HANDLE handle[ThreadNum]; g_count = 0; for (int i = 0; i < ThreadNum; ++i) { handle[i] = (HANDLE)_beginthreadex(NULL, 0, Func, (LPVOID)&i, 0, NULL); } WaitForMultipleObjects(ThreadNum, handle, TRUE, INFINITE); system("pause"); return 0; }
要求:
子线程输出的线程序号不能重复。(主线程和子线程需要同步)
全局变量g_count的输出必须递增。(子线程之间需要互斥)
1,用临界区CRITICAL_SECTION来解决子线程之间的互斥
CRITICAL_SECTION g_section;//声明一个临界区资源 InitializeCriticalSection(&g_section);//初始化 EnterCriticalSection(&g_section);//开始进入临界区代码段 LeaveCriticalSection(&g_section);//离开临界区代码段 DeleteCriticalSection(&g_section);//销毁
#include "stdafx.h" #include <windows.h> #include <process.h> int g_count; const int ThreadNum = 10; CRITICAL_SECTION g_section; unsigned int __stdcall Func(LPVOID pm) { int id = *(int*)pm; Sleep(10); EnterCriticalSection(&g_section);//进入临界区后各个线程之间互斥 g_count++; //InterlockedIncrement((LPLONG)&g_count); printf_s("id=%d,count=%d ", id, g_count); LeaveCriticalSection(&g_section); return 0; } int main() { InitializeCriticalSection(&g_section); HANDLE handle[ThreadNum]; g_count = 0; for (int i = 0; i < ThreadNum; ++i) { handle[i] = (HANDLE)_beginthreadex(NULL, 0, Func, (LPVOID)&i, 0, NULL); } WaitForMultipleObjects(ThreadNum, handle, TRUE, INFINITE); DeleteCriticalSection(&g_section); system("pause"); return 0; }
2用事件解决主线程和子线程的同步问题
//CreateEvent创建一个事件
HANDLE CreateEvent(
LPSECURITY_ATTRIBUTES lpEventAttributes,//安全参数,一般为NULL
BOOL bManualReset, //TRUE手动(SetEvent后需要ResetEvent) , FALSE自动,对事件对象调用WaitForSingleObject后自动是对象变成未触发的状态
BOOL bInitialState, //TRUE 初始状态就是触发状态
LPCTSTR lpName //事件对象的名字,传入NULL表示匿名的事件对象
);
//SetEvent 触发一个事件内核对象,必有一个或者多个等待状态的线程变成可调度的状态
BOOL SetEvent(HANDLE hEvent);
//ResetEvent 事件变成未触发状态
BOOL ResetEvent (HANDLE hEvent);
最后的代码如下
#include "stdafx.h" #include <windows.h> #include <process.h> int g_count; const int ThreadNum = 10; CRITICAL_SECTION g_section; HANDLE g_handle; unsigned int __stdcall Func(LPVOID pm) { int id = *(int*)pm; SetEvent(g_handle);//事件被触发后,线程变成可调度状态 Sleep(10); EnterCriticalSection(&g_section);//进入临界区 g_count++; printf_s("id=%d,count=%d ", id, g_count);//离开临界区 LeaveCriticalSection(&g_section); return 0; } int main() { g_handle = CreateEvent(NULL, FALSE, FALSE, NULL); InitializeCriticalSection(&g_section); HANDLE handle[ThreadNum]; g_count = 0; for (int i = 0; i < ThreadNum; ++i) { handle[i] = (HANDLE)_beginthreadex(NULL, 0, Func, &i, 0, NULL); WaitForSingleObject(g_handle, INFINITE);//等待事件被触发 } WaitForMultipleObjects(ThreadNum, handle, TRUE, INFINITE);//等待所有的子线程被触发 CloseHandle(g_handle); DeleteCriticalSection(&g_section); system("pause"); return 0; }
输出
id没有相同的,说明主线程和子线程之间已经同步,
count递增,说明子线程之间已经互斥