事件对象也可以通过通知操作的方式来保持线程的同步。并且可以实现不同进程中的线程同步操作。
信号量包含的几个操作原语:
CreateEvent() 创建一个信号量
OpenEvent() 打开一个事件
SetEvent() 回置事件
WaitForSingleObject() 等待一个事件
WaitForMultipleObjects() 等待多个事件
WaitForMultipleObjects 函数原型:
参数nCount指定了要等待的内核对象的数目,存放这些内核对象的数组由lpHandles来指向。fWaitAll对指定的这nCount个内核对象的两种等待方式进行了指定,为TRUE时当所有对象都被通知时函数才会返回,为FALSE则只要其中任何一个得到通知就可以返回。dwMilliseconds在这里的作用与在WaitForSingleObject()中的作用是完全一致的。如果等待超时,函数将返回WAIT_TIMEOUT。WaitForMultipleObjects( IN DWORD nCount, // 等待句柄数 IN CONST HANDLE *lpHandles, //指向句柄数组 IN BOOL bWaitAll, //是否完全等待标志 IN DWORD dwMilliseconds //等待时间 )
//事件数组 HANDLE global_Events[2]; // 共享资源 char global_Array[256]; void InitializeArray() { for(int i = 0;i<256;i++) { global_Array[i]=I; } } UINT Global_ThreadOne(LPVOID pParam) { CEdit *ptr=(CEdit *)pParam; ptr->SetWindowText(""); for(int i = 0;i<256;i++) { global_Array[i]=O; ptr->SetWindowText(global_Array); Sleep(10); } //回置事件 SetEvent(global_Events[0]); return 0; } UINT Global_ThreadTwo(LPVOID pParam) { CEdit *ptr=(CEdit *)pParam; ptr->SetWindowText(""); for(int i = 0;i<256;i++) { global_Array[i]=T; ptr->SetWindowText(global_Array); Sleep(10); } //回置事件 SetEvent(global_Events[1]); return 0; } UINT Global_ThreadThree(LPVOID pParam) { CEdit *ptr=(CEdit *)pParam; ptr->SetWindowText(""); //等待两个事件都被回置 WaitForMultipleObjects(2, global_Events, true, INFINITE); for(int i = 0;i<256;i++) { global_Array[i]=H; ptr->SetWindowText(global_Array); Sleep(10); } return 0; } void CEventDlg::OnBnClickedButtonStart() { for (int i = 0; i < 2; i++) { //实例化事件 global_Events[i]=CreateEvent(NULL,false,false,NULL); } CWinThread *ptrOne = AfxBeginThread(Global_ThreadOne, &m_One, THREAD_PRIORITY_NORMAL, 0, CREATE_SUSPENDED); ptrOne->ResumeThread(); //Start the second Thread CWinThread *ptrTwo = AfxBeginThread(Global_ThreadTwo, &m_Two, THREAD_PRIORITY_NORMAL, 0, CREATE_SUSPENDED); ptrTwo->ResumeThread(); //Start the Third Thread CWinThread *ptrThree = AfxBeginThread(Global_ThreadThree, &m_Three, THREAD_PRIORITY_NORMAL, 0, CREATE_SUSPENDED); ptrThree->ResumeThread(); // TODO: Add your control notification handler code here }
事件可以实现不同进程中的线程同步操作,并且可以方便的实现多个线程的优先比较等待操作,例如写多个WaitForSingleObject来代替WaitForMultipleObjects从而使编程更加灵活。