WaitForSingleObject函数,其函数原型为:DWORD WaitForSingleObject(HANDLE hHandle,DWORD
dwMilliseconds);
hHandle为要监视的对象(一般为同步对象,也可以是线程)的句柄;
dwMilliseconds为hHandle对象所设置的超时值,单位为毫秒;
当在某一线程中调用该函数时,线程暂时挂起,系统监视hHandle所指向的对象的状态。如果在挂起的dwMilliseconds毫秒内,线程所等待
的对象变为有信号状态,则该函数立即返回;如果超时时间已经到达dwMilliseconds毫秒,但hHandle所指向的对象还没有变成有信号状态,函
数照样返回。参数dwMilliseconds有两个具有特殊意义的值:0和INFINITE。若为0,则该函数立即返回;若为INFINITE,则线程一直被挂起,
直到hHandle所指向的对象变为有信号状态时为止。
1、线程函数发简单参数
void ThreadFunc(int integer)
{ int i; for(i=0;i<integer;i++) { Beep(200,50); Sleep(2000); }}void CMultiThread2Dlg::OnBnClickedStart()
{ UpdateData(TRUE); int integer=m_nCount; hThread=CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ThreadFunc, (VOID*)integer, 0, &ThreadID); GetDlgItem(IDC_START)->EnableWindow(FALSE); WaitForSingleObject(hThread,INFINITE); //主线程挂起,等待hThread线程执行完毕在返回 GetDlgItem(IDC_START)->EnableWindow(TRUE); //只有ThreadFunc执行完毕,WaitForSingleObject返回,才会执行此句。}2.线程函数发结构参数,要用到强制转换
UINT ThreadFunc(LPVOID lpParam)
{ threadInfo* pInfo=(threadInfo*)lpParam; for(int i=0;i<100;i++) { int nTemp=pInfo->nMilliSecond; pInfo->pctrlProgress->SetPos(i); Sleep(nTemp); } return 0;}void CMultiThread3Dlg::OnBnClickedStart()
{ UpdateData(TRUE); Info.nMilliSecond=m_nMilliSecond; Info.pctrlProgress=&m_ctrlProgress; hThread=CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ThreadFunc, &Info, 0, &ThreadID); //WaitForSingleObject(hThread, INFINITE); //加此举引起死锁,因为主线程挂起,等线程hThread返回, //但是在子线程函数ThreadFunc中,在设置进度条, //子线程会一直在等待主线程将刷新(Paint)消息处理完毕返回才会检测通知事件。 //最终二者相互等待,死锁}*********关于死锁************
产生死锁的原因
产生死锁的主要原因可归结为以下两点。
(1)竞争资源(2)进程推进顺序不当产生死锁的必要条件
(1)互斥条件
一个资源在一段时间内只能被一个进程所使用,具有排它性。(2)请求和保持条件一个进程在请求新资源而阻塞时,对已获得资源又保持不放。(3)不剥夺条件进程已获得的资源,在未使用完之前不能被剥夺,只能在使用完时由自己释放。(4)环路等待条件在发生死锁时,必然存在一个进程--资源的环形链。即进程集合{P1,P2,...,Pn}中的P1正在等待P2占用的资源,P2正在等待P3占用的资源,...,Pn正在等待P1占用的资源。只要同时具备上述4个必要条件,系统就会发生死锁,只要上述条件之一不满足,系统就不会发生死锁。
处理死锁的策略
1.忽略该问题。例如鸵鸟算法,该算法可以应用在极少发生死锁的的情况下。为什么叫鸵鸟算法呢,因为传说中鸵鸟看到危险就把头埋在地底下,可能鸵鸟觉得看不到危险也就没危险了吧。跟掩耳盗铃有点像。
2.检测死锁并且恢复。3.仔细地对资源进行动态分配,以避免死锁。4.通过破除死锁四个必要条件之一,来防止死锁产生。