等待一个对象 | 等待多个对象 |
---|---|
WaitForSingleObject() | WaitForMultipleObjects() |
在指定时间内等待一个对象 | 在指定时间内等待多个对象 |
等待一个对象
DWORD WaitForSingleObject(
HANDLE hHandle, //对象句柄
DWORD dwMilliseconds //等待时间
);
等待多个对象
DWORD WaitForMultipleObject(
DWORD nCount, //句柄数组中的句柄数
const HANDLE *lpHandle, //指向对象句柄数组的指针
BOOL fwaitALL, //等待类型
DWORD dwMilliseconds //等待时间
);
可等待的对象列表
我们需要立一个Flag,用于在主子线程之间相互告知运行状态。
Flag = 信号量
创建一个信号量
hHandle1 = CreateSemaphore(NULL, 0,1, "SemaphoreName1");//创建一个信号量(安全标识符,信号量初始态,信号量最大值,信号量名称)
打开一个信号量
hHandle1 = OpenSemaphore( SYNCHRONIZE ISEMAPHORE_ MODIFY_ STATE, NULL,"SemaphoreName1" );
释放信号量
rc = ReleaseSemaphore (hHandle1, 1, NULL)(我们需要释放的信号量,进行增几的操作,NULL);
等待单个对象
dRes = WaitForSingleObject(hHandle1 , INFINITE); // 主线程无限期地等待子线程结束(句柄,如果没有释放无限运行)
等待多个对象
dRes = WaitForMultiple0bjects(3, hHandles, 1, INFINITE); //第三个参数为1或true时,等待数组中所有对象完成,为0或者false时满足一个任务结束就可继续执行
实验一 线程的同步之等待单个对象
子线程 | 主线程 |
---|---|
用于制作麻辣香锅,制作用时5秒 | 等待子线程执行完毕,打印“开始食用香锅” |
实验二 线程的同步之等待多个对象
子线程1 | 子线程2 | 子线程3 | 主线程 |
---|---|---|---|
用于制作麻辣香锅,制作用时5秒 | 用于制作什锦菇,制作用时3秒 | 用于制作米饭,制作用时6秒 | 等待多个子线程执行完毕,打印”开动了!“ |
实验一主要内容及代码
static HANDLE hHandle1 = NULL; //静态变量hHandle1用于存放打开的信号量
void chef(){ //用于执行相关的业务逻辑
printf("麻辣香锅开始制作,预计等待时间5s. \n");
Sleep(5000);
printf("麻辣香锅制作完成! \n");
BOOL rc;
DWORD err;
rc = ReleaseSemaphore(hHandle1,1,NULL); //释放信号量
err = GetLastError(); //检测上一条语句是否执行成功
printf("ReleaseSemaphore err = %d\n",err);
if(rc == 0)
{
printf("Semaphore Release Fail!\n");
}
else{
printf("Semaphore Release Success! rc = %d\n",rc);
}
}
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
int nRetCode = 0;
DWORD dRes,err;
hHandle1=CreateSemaphore(NULL,0,1,"SemaphoreName1");//创建一个信号量
if (hHandle1==NULL)
printf("Semaphore Create Fail!\n");
else
printf("Semaphore Create Success!\n");
hHandle1=OpenSemaphore(SYNCHRONIZE|SEMAPHORE_MODIFY_STATE,
NULL,
"SemaphoreName1"); //打开信号量
if (hHandle1 == NULL)
printf("Semaphore Open Fail!\n");
else
printf("Semaphore Open Success!\n");
HANDLE handle1 = NULL;
DWORD ThreadID1 = NULL;
handle1 = CreateThread((LPSECURITY_ATTRIBUTES)NULL,
0,
(LPTHREAD_START_ROUTINE) chef,
(LPVOID)NULL,
0,
&ThreadID1); //创见一个新的线程
dRes=WaitForSingleObject(hHandle1,INFINITE); //主线程等待子线程结束
err=GetLastError(); //检测上一条是否执行
if(err == 0){
printf("麻辣香锅上菜完毕,请开动吧.\n");
}
else{
printf("WaitForSingleObject err = %d\n",err);
if (dRes==WAIT_TIMEOUT)
printf("TIMEOUT!dRes=%d\n",dRes);
else if (dRes==WAIT_OBJECT_0)
printf("WAIT_OBJECT!dRes=%d\n",dRes);
else if (dRes==WAIT_ABANDONED)
printf("WAIT_ABANDONED!dRes=%d\n",dRes);
else
printf("dRes =%d\n",dRes);
}
return nRetCode;
}
实验二主要内容及代码
void chef(int meal_code){
if(meal_code == 0){
Sleep(5000);
printf("麻辣香锅制作完成! \n");
}
else if(meal_code == 1){
Sleep(3000);
printf("什锦菇制作完成! \n");
}
else if(meal_code == 2){
Sleep(6000);
printf("米饭制作完成! \n");
}
}
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
int nRetCode = 0;
DWORD dRes,err;
HANDLE handle1 = NULL;
HANDLE handle2 = NULL;
HANDLE handle3 = NULL;
DWORD ThreadID1 = NULL;
DWORD ThreadID2 = NULL;
DWORD ThreadID3 = NULL;
int a = 0;
int b = 1;
int c = 2;
handle1 = CreateThread((LPSECURITY_ATTRIBUTES)NULL,
0,
(LPTHREAD_START_ROUTINE) chef,
(LPVOID)a,
0,
&ThreadID1);
handle2 = CreateThread((LPSECURITY_ATTRIBUTES)NULL,
0,
(LPTHREAD_START_ROUTINE) chef,
(LPVOID)b,
0,
&ThreadID2);
handle3 = CreateThread((LPSECURITY_ATTRIBUTES)NULL,
0,
(LPTHREAD_START_ROUTINE) chef,
(LPVOID)c,
0,
&ThreadID3);
HANDLE hHandles[3]; //用于存放以上三个线程
hHandles[0] = handle1;
hHandles[1] = handle2;
hHandles[2] = handle3;
dRes=WaitForMultipleObjects(3,hHandles,1,INFINITE); //第三个参数为1,等待所有对象完成
//dRes=WaitForMultipleObjects(3,hHandles,0,INFINITE); //第三个参数为0,只需要等待一个对象完成
err=GetLastError(); //检测语句执行是否成功
if(err == 0){
printf("所有的餐点已经上齐,请开动吧.\n");
}
else{
printf("WaitForSingleObject err = %d\n",err);
if (dRes==WAIT_TIMEOUT)
printf("TIMEOUT!dRes=%d\n",dRes);
else if (dRes==WAIT_OBJECT_0)
printf("WAIT_OBJECT!dRes=%d\n",dRes);
else if (dRes==WAIT_ABANDONED)
printf("WAIT_ABANDONED!dRes=%d\n",dRes);
else
printf("dRes =%d\n",dRes);
}
return nRetCode;
}
实验一
实验中遇到的问题