WaitForSingleObject崩溃了

时间:2011-12-01 16:08:01

标签: c++ multithreading winapi

以下是代码。代码不完整,我省略了释放资源部分和QueryRes逻辑的实现。

#define N 5

/*simply resources manager which has N shared resources*/
class ResourceManager
{
public:
    ResourceManager()
    {
            for (int i = 0; i < N; ++i)
              resources[i] = CreateMutex(NULL, FALSE, NULL);
    }
/*CreateMutex for on resources array in ctor*/
/*CloseHandle() in dtor and ReleaseMutex in another function which is called after QueryRes*/

        void QueryRes(int i)
        {
          WaitForSingleObject(resources[i], INFINITE); //(*) Here is the problem
        }

private:
        HANDLE resources[N];
};

/*User who asks for resource time-to-time*/
class User
{
public:
    User(ResourceManager& res_holder_, int res_num) : resource_holder(resource_holder), resource_to_query(res_num) {}

    void WorkWithResource()
    {
            while(1)
            {
                    resource_holder.QueryRes(resource_to_query);
            }
    }


    static void Run (void* params)
    {
            static_cast<User*>(params)->WorkWithResource();
    }

private:
    ResourceManager& resource_holder;
    int resource_to_query;
};

int main()
{
        ResourceManager resource_manager;
        User* users[5];
        HANDLE threads[5];

        for (size_t i = 0 ; i < 5; ++i)
        {
                users[i] = new User(resource_manager, i % 5);
                threads[i] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)&User::Run, users[i], 0, NULL);
        }
        WaitForMultipleObjects(5, threads, true, INFINITE);


        return 0;
}

在(*)处,当函数在已锁定的互斥锁上执行WaitForSingleObject时,我会收到“访问冲突异常”。

我也试过

 while(WaitForSingleObject(resources[i], INFINITE) != WAIT_OBJECT_0) 

得到了相同的结果。

为什么我会得到例外?

我尝试过vc 2003,2008和2010.我不能使用boost / pthreads / etc.

谢谢。

2 个答案:

答案 0 :(得分:4)

错误在于

的构造函数
User(ResourceManager& res_holder_, int res_num) : resource_holder(resource_holder), resource_to_query(res_num)    {   }

你应该

User(ResourceManager& res_holder_, int res_num) : resource_holder(**res_holder_**), resource_to_query(res_num)    {   }

而不是!

答案 1 :(得分:1)

当你遇到访问冲突(或者在其他平台上遇到段错误,虽然一般来说这是一个糟糕的指针取消引用),通常从查看代码中可以明显看出原因......在这种情况下,没有任何东西突然出现在我面前你发布了。根据你所说的,我的猜测是砸碎了堆栈。

然而,一些建议......当您看到无法解释的访问冲突时,第一步不是发布到Stack Overflow。在调试器中查看它!如果您从Microsoft下载“Windows调试工具”并使用“windbg”,并学习如何使用它,它会告诉您有关此崩溃的更多信息,而不是您认为可以知道的 - 它尝试访问的错误地址是,反汇编WaitForMultipleObjects,以便您可以看到它正在做什么以及地址来自哪里等等。我通常会发现有一些kru和{{在windbg中的命令,导致错误的指针取消引用变得非常明显。