我貼一下我的代碼,為什麼會出現返回87的問題
#include <iostream>
#include <cstdio>
#include <cstring>
#include <windows.h>
#include <map>
using namespace std;
#define random (rand()*1000)/RAND_MAX // random audience
int movieNumber;
int Count[1000];
HANDLE Mutex[1000];
HANDLE HallMutex[3];
map<int ,DWORD >MAP;
DWORD WINAPI VideoShow(LPVOID vid) {
int i = (int)vid;
printf("來個一個觀眾,想看%d影片\n",i);
WaitForSingleObject(Mutex[i],-1);
Count[i]++;
if (Count[i] == 1) {
DWORD index = WaitForMultipleObjects(3,HallMutex,FALSE,-1);
if (index == WAIT_OBJECT_0 || index == WAIT_OBJECT_0 + 1 || index == WAIT_OBJECT_0 + 2) {
MAP[i] = index - WAIT_OBJECT_0;
printf("觀眾進入錄像廳\n");
printf("錄像廳%d正在放映影片%d,有%d個觀眾\n",index,i,1);
}
else {
ExitProcess(GetLastError());
}
}
else {
printf("觀眾進入錄像廳\n");
printf("錄像廳%d正在放映影片%d,有%d個觀眾\n",MAP[i],i,Count[i]);
}
ReleaseMutex(Mutex[i]);
Sleep(2000);
WaitForSingleObject(Mutex[i],-1);
Count[i]--;
printf("有一個觀眾從正在播放影片%d的錄像廳%d離開,還有%d個人\n",i,MAP[i],Count[i]);
if (Count[i] == 0) {
printf("錄像廳%d放映結束\n",MAP[i]);
ReleaseMutex(HallMutex[MAP[i]]);
}
ReleaseMutex(Mutex[i]);
}
int main () {
printf("請輸入電影院裡電影的數目\n");
cin >> movieNumber;
for (int i = 0;i < 3;i++) {
HallMutex[i] = CreateMutex(NULL,0,NULL);
}
for (int i = 0;i < movieNumber;i++) {
Mutex[i] = CreateMutex(NULL,0,NULL);
}
HANDLE hThread;
while (1) {
Sleep(random);
DWORD a = rand() % movieNumber;
hThread = CreateThread(NULL,0,VideoShow,LPVOID(a),0,NULL);
}
}
如oyljerry所說,你的129是WAIT_ABANDONED_0+1
這個是指:有一個Mutex,它的擁有者線程已經結束,但是那個線程沒有釋放Mutex。
為此,我以5執行了你的代碼,結果如下
請輸入電影院裡電影的數目
5
來個一個觀眾,想看2影片
觀眾進入錄像廳
錄像廳0正在放映影片2,有1個觀眾
來個一個觀眾,想看0影片
觀眾進入錄像廳
錄像廳1正在放映影片0,有1個觀眾
來個一個觀眾,想看4影片
觀眾進入錄像廳
錄像廳2正在放映影片4,有1個觀眾
來個一個觀眾,想看3影片
來個一個觀眾,想看4影片
觀眾進入錄像廳
錄像廳2正在放映影片4,有2個觀眾
有一個觀眾從正在播放影片2的錄像廳0離開,還有0個人
錄像廳0放映結束
觀眾進入錄像廳
錄像廳0正在放映影片3,有1個觀眾
來個一個觀眾,想看0影片
觀眾進入錄像廳
錄像廳1正在放映影片0,有2個觀眾
有一個觀眾從正在播放影片0的錄像廳1離開,還有1個人
有一個觀眾從正在播放影片4的錄像廳2離開,還有1個人
來個一個觀眾,想看2影片
LastError = 87
打印LastError的位置就是出現129的時候,經分析,執行的線程情況如下,其中A.B.C...代表來的人(在本例中相當於線程),1,2,3代表影片編號
+-等--+-1廳-+-2廳-+-3廳-+
| A2--|->A2 | | |
| B0--|-----|->B0 | |
| C4--|-----|-----|->C4 |
| D3 | | | |
| E4--|-----|-----|->E4 |
| A2<-|--A2 | | |
| D3--|->D3 | | |
| F0--|-----|->F0 | |
| B0<-|-----|--B0 | |
| C4<-|-----|-----|--C4 |
| G2 | | | |ERROR
由此可見在F0來看電影之後,B0離開了電影院.而2廳的Mutex是B0線程創建的.因此它退出但是沒有ReleaseMutex(當然是因為業務如此)
然後到G2的時候,需要找一個廳時,就會報129(WAIT_ABANDONED_0+1)
解決方法,對如題的簡單應用來說,可以直接忽略WAIT_ABANDONED_0這組數據重新等待,因此把代碼略改一下,如下所示
#include <iostream>
#include <cstdio>
#include <cstring>
#include <windows.h>
#include <map>
using namespace std;
#define random (rand()*1000)/RAND_MAX // random audience
int movieNumber;
int Count[1000];
HANDLE Mutex[1000];
HANDLE HallMutex[3];
map<int, DWORD >MAP;
DWORD WINAPI VideoShow(LPVOID vid) {
int i = (int)vid;
printf("來個一個觀眾,想看%d影片\n", i);
WaitForSingleObject(Mutex[i], -1);
Count[i]++;
if (Count[i] == 1) {
DWORD index = 0;
bool done = false;
do
{
index = WaitForMultipleObjects(3, HallMutex, FALSE, -1);
if (index == WAIT_OBJECT_0 || index == WAIT_OBJECT_0 + 1 || index == WAIT_OBJECT_0 + 2) {
MAP[i] = index - WAIT_OBJECT_0;
printf("觀眾進入錄像廳\n");
printf("錄像廳%d正在放映影片%d,有%d個觀眾\n", index, i, 1);
done = true;
}
else if (index == 0xFFFFFFFF)
{
int e = GetLastError();
printf("LastError = %d\n", e);
ExitProcess(e);
}
else
{
Sleep(0);
}
} while (!done);
}
else {
printf("觀眾進入錄像廳\n");
printf("錄像廳%d正在放映影片%d,有%d個觀眾\n", MAP[i], i, Count[i]);
}
ReleaseMutex(Mutex[i]);
Sleep(2000);
WaitForSingleObject(Mutex[i], -1);
Count[i]--;
printf("有一個觀眾從正在播放影片%d的錄像廳%d離開,還有%d個人\n", i, MAP[i], Count[i]);
if (Count[i] == 0) {
printf("錄像廳%d放映結束\n", MAP[i]);
ReleaseMutex(HallMutex[MAP[i]]);
}
ReleaseMutex(Mutex[i]);
}
int main() {
printf("請輸入電影院裡電影的數目\n");
cin >> movieNumber;
for (int i = 0; i < 3; i++) {
HallMutex[i] = CreateMutex(NULL, 0, NULL);
}
for (int i = 0; i < movieNumber; i++) {
Mutex[i] = CreateMutex(NULL, 0, NULL);
}
HANDLE hThread;
while (1) {
Sleep(random);
DWORD a = rand() % movieNumber;
hThread = CreateThread(NULL, 0, VideoShow, LPVOID(a), 0, NULL);
}
}
對於較復雜的情況,這樣使用可能引起其他的同步問題。在這樣的情況下,建議對每個放映廳創建線程,單獨管理。