程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 更多編程語言 >> 編程綜合問答 >> ait or ultiple bject-C++多線程WaitForMultipleObject 返回值為87 怎麼回事

ait or ultiple bject-C++多線程WaitForMultipleObject 返回值為87 怎麼回事

編輯:編程綜合問答
C++多線程WaitForMultipleObject 返回值為87 怎麼回事

我貼一下我的代碼,為什麼會出現返回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);
    }
}

對於較復雜的情況,這樣使用可能引起其他的同步問題。在這樣的情況下,建議對每個放映廳創建線程,單獨管理。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved