WaitForSingleObject падает - PullRequest
       3

WaitForSingleObject падает

0 голосов
/ 01 декабря 2011

Вот код ниже. Код не завершен, я пропустил освобождение части ресурсов и реализацию логики 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 / и т.д.

Спасибо.

Ответы [ 2 ]

4 голосов
/ 01 декабря 2011

Ошибка заключается в конструкторе

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 голос
/ 01 декабря 2011

Когда вы получаете нарушение доступа (или segfault на других платформах, хотя, вообще говоря, это плохая разыменование указателя), часто причина очевидна при взгляде на код ... В этом случае у меня ничего не выскакивает из того, чтоВы отправили.Мое предположение, основанное на том, что вы сказали, что-то разбило стек.

Однако, несколько советов ... Когда вы видите нарушение доступа, которое вы не можете объяснить, первым шагом не является публикация в переполнение стека.,Посмотри на это в отладчике!Если вы загрузите «Средства отладки для Windows» от Microsoft и будете использовать «windbg» и узнаете, как его использовать, он расскажет вам больше об этом сбое, чем вы когда-либо думали, что сможете узнать - какой плохой адрес он пытался получить,дизассемблирование WaitForMultipleObjects, чтобы вы могли видеть, что он делает и откуда пришел адрес и т. д. Я обычно нахожу с помощью нескольких команд k, r, u и dq в windbg, причинаплохая разыменование указателя становится довольно очевидным.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...