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 = %dn", 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);
    }
}

对于较复杂的情况,这样使用可能引起其他的同步问题。在这样的情况下,建议对每个放映厅创建线程,单独管理。

解决方案二:

是GetLastError返回87还是WaitForMultipleObjects返回87?
WaitForMultipleObjects应该不会返回87的。
GetLastError返回87是参数错误。
看程序应该是第二种情况。

解决方案三:

对,WatiForMultipleObjects返回129,但是我传的参数的个数是3,怎么可能返回129呢,不知道哪里错了 知常曰明

解决方案四:

你可能是这个问题
http://blog.csdn.net/guanzhongs/article/details/1544464
返回值Index和WAIT_OBJECT_0关系

最小的是WAIT_OBJECT_0
后面用WAIT_ABANDONED_0 + nCount – 1

解决方案五:

WAIT_ABANDONED_0 is defined as 0x00000080L.)

WAIT_ABANDONED_0 to (WAIT_ABANDONED_0 + nCount– 1)
If bWaitAll is TRUE, the return value indicates that the state of all specified objects is signaled and at least one of the objects is an abandoned mutex object.
If bWaitAll is FALSE, the return value minus WAIT_ABANDONED_0 indicates the lpHandles array index of an abandoned mutex object that satisfied the wait. Ownership of the mutex object is granted to the calling thread, and the mutex is set to nonsignaled.
If a mutex was protecting persistent state information, you should check it for consistency.

129是WAIT_ABANDONED_0+1

解决方案六:

回复 oyljerry 为什么返回值还有0 1 2

时间: 2024-09-19 09:18:01

ait or ultiple bject-C++多线程WaitForMultipleObject 返回值为87 怎么回事的相关文章

handle-waitfordebugevent 返回值是ERROR_INVALID_HANDLE怎么回事

问题描述 waitfordebugevent 返回值是ERROR_INVALID_HANDLE怎么回事 waitfordebugevent 返回值是ERROR_INVALID_HANDLE怎么回事 ? 解决方案 你等待的参数中,句柄是否为合法句柄 解决方案二: 这个函数是windowsAPI函数,我传的是一个结构的地址,具体的值是由windows进行填充的.

index-Index没有返回值是怎麽回事,求指导

问题描述 Index没有返回值是怎麽回事,求指导 #include #include #include #define MAXSTLEN 234 typedef char SString[MAXSTLEN+1]; int Index(SString S,SString T,int pos) {int i=pos,j=1,len1,len2; len1=strlen(S); len2=strlen(T); while((i<=len1)&&(j<=len2)) { if(S[i]

多线程- 我的java难道是盗版吗(调用有返回值的函数无响应)

问题描述 我的java难道是盗版吗(调用有返回值的函数无响应) boolean flag = pcSystem.returnTenderResult(bidDocu,tenderDocu); 我在自定义pcSystem类中调用一个具有boolean返回值的函数returnTenderResult(synchronized) 这条语句的上一条语句都会执行,而returnTenderResult内方法一定概率上不执行 (方法内的第一条语句都没有执行,还不涉及方法内具体逻辑),系统涉及了多线程, 这是

请问多线程并发计算,是不是只能通过变量获得返回值?

问题描述 请问多线程并发计算,是不是只能通过变量获得返回值? 请问多线程并发计算,是不是只能通过变量获得返回值?如果不用变量,线程函数里的返回值返回到哪里去了? 解决方案 和你调用一般的函数一样,如果你不用变量接收,那么,这个返回值就被忽略了. 解决方案二: 可以用公共变量,但是要注意冲突,还可以通过发消息,给其他线程

mfc-MFC多线程计算浮点数组,关于返回值的自动保存

问题描述 MFC多线程计算浮点数组,关于返回值的自动保存 MFC多线程计算浮点数组,返回值能不能进行自动保存,并且如果出错,就自动恢复执行计算? 解决方案 你可以把结果保存到外部文件中,然后重新执行就从文件中读取. 解决方案二: 你想要保存到哪里?出错指的是什么出错?程序崩溃,要捕获异常,重新执行计算?

MFC多线程并发怎么按照线程顺序输出返回值?

问题描述 MFC多线程并发怎么按照线程顺序输出返回值? 多线程MFC程序,并发执行后分别按照顺序来返回结果,主线程接收这些返回值并且输出.显示,怎么做? 解决方案 你可以用信号量,让主线程等待子线程完成,用WaitForMultipleObjects WaitForSingleObjects函数 解决方案二: 可以用事件做线程同步.

java多线程返回值使用示例(callable与futuretask)_java

Callable接口类似于Runnable,从名字就可以看出来了,但是Runnable不会返回结果,并且无法抛出返回结果的异常,而Callable功能更强大一些,被线程执行后,可以返回值,这个返回值可以被Future拿到,也就是说,Future可以拿到异步执行任务的返回值,下面来看一个简单的例子 复制代码 代码如下: package com.future.test; import java.io.FileNotFoundException;import java.io.IOException;i

线程中的回调函数如何获得返回值,请高手开悟,在线等......

问题描述 普通回调方法:classA{classBxx=newclassB();stringss=k.ca(tm);stringtm(stringxm){returnxm+"一杯醉倒";}}classB{publicdelegatestringtc();publicstringca(tcmm){MessageBox.Show("到这里了!");returnmm("我");}}执行stringss=k.ca(tm);语句后,得到回调函数tm的返回值

并发调用接口 需要参数和返回值

问题描述 程序中需要调用两个接口因为接口都比较费时所以准备并发调用也可以说是多线程调用吧但是调用需要传递参数而且还要接收返回值大神们有什么办法吗? 解决方案 解决方案二:那就是接口设计错误了,应该使用异步的接口方法.解决方案三:多线程可以传参啊3种传参方式1.封装到类里去2.object参数3.委托传参解决方案四:如果你几个接口必须按顺序执行,那么你异步没戏比如你有三个接口:IA,IB,ICIB的参数用到了IA的返回结果,IC用到了IB的返回结果,这样你还怎么异步?解决方案五:例如,你有两个方法