waitforsingeobject перестает ждать, когда он получает событие сброса - PullRequest
0 голосов

проблема.У меня есть отель на 10 номеров, и мне нужно смоделировать его поведение с помощью потоков, событий и мьютекса.Если там более 10 человек, то они будут ждать до следующего дня.

Ошибка появляется, когда я пытаюсь разместить более 10 человек.

В функции ветка 'freeRoom' ждетсобытие hShouldFree [i].Каждый элемент массива hShouldFree устанавливается на состояние сигнала на сервере после нажатия клавиши enter.Затем в функции 'freeRoom' поток пробуждается, освобождает i-ую комнату и сбрасывает событие hShouldFree [i], поэтому его нельзя освободить, когда оно уже свободно.Однако то, что я получаю, это это .Это освобождает свободные номера.

Вот код сервера.

#include <windows.h>
#include <time.h>
#include <stdio.h>
#include <conio.h>
#include <iostream>
#include <string>

using namespace std;

const int n = 10;

HANDLE hStart, hFull, hWork, hShouldFree[n];

void CloseHandles() {
CloseHandle(hStart);
CloseHandle(hFull);
CloseHandle(hWork);
CloseHandle(hShouldFree);

}

void OpenSFHandles()
{
hShouldFree[0] = OpenEventW(EVENT_ALL_ACCESS, TRUE, (LPCWSTR)"PlsFree0");
hShouldFree[1] = OpenEventW(EVENT_ALL_ACCESS, TRUE, (LPCWSTR)"PlsFree1");
hShouldFree[2] = OpenEventW(EVENT_ALL_ACCESS, TRUE, (LPCWSTR)"PlsFree2");
hShouldFree[3] = OpenEventW(EVENT_ALL_ACCESS, TRUE, (LPCWSTR)"PlsFree3");
hShouldFree[4] = OpenEventW(EVENT_ALL_ACCESS, TRUE, (LPCWSTR)"PlsFree4");
hShouldFree[5] = OpenEventW(EVENT_ALL_ACCESS, TRUE, (LPCWSTR)"PlsFree5");
hShouldFree[6] = OpenEventW(EVENT_ALL_ACCESS, TRUE, (LPCWSTR)"PlsFree6");
hShouldFree[7] = OpenEventW(EVENT_ALL_ACCESS, TRUE, (LPCWSTR)"PlsFree7");
hShouldFree[8] = OpenEventW(EVENT_ALL_ACCESS, TRUE, (LPCWSTR)"PlsFree8");
hShouldFree[9] = OpenEventW(EVENT_ALL_ACCESS, TRUE, (LPCWSTR)"PlsFree9");
}

int main()
{
    hStart = CreateEvent(NULL, FALSE, FALSE, (LPCWSTR)"START");
    WaitForSingleObject(hStart, INFINITE);
    hWork = OpenEventW(EVENT_ALL_ACCESS, TRUE, (LPCWSTR)"WORK");
    hFull = OpenEventW(EVENT_ALL_ACCESS, TRUE, (LPCWSTR)"FULL");
    OpenSFHandles();
    char c;
    while (WaitForSingleObject(hWork, 0) == WAIT_OBJECT_0)
    {
        WaitForSingleObject(hFull, INFINITE);

        cout << "Hotel is full\nPress esc to quit\nPress any other key to     set time for next morning\n";
        OpenSFHandles();
        c =_getch();
        if (c == 27)
        {
            CloseHandles();
            system("pause");
            return 0;
        }
        else
        {
            ResetEvent(hFull);
            for (int i = 0; i < n; i++) {
                SetEvent(hShouldFree[i]);
            }
        }
        }
    CloseHandles();
    cout << "Client has been closed\n";
    system("pause");
    return 0;
}

Вот код клиента

#include <windows.h>
#include <conio.h> 
#include <iostream>
#include <string>
#include <fstream>
using namespace std;


struct room {
    int number;
    bool isfree;
};


int k, k1, k2;  //number of people, people left to occpy, people left to free

//number of rooms
const int n = 10;
room hotel[n];
int ToOccupy = 0; // index for occupation
int ToFree = 0; // index for freeing

HANDLE hEventFree[n], hShouldFree[n], hFull,
hMutex;


void init_hotel(room* a, int num)
{
    for (int i = 0; i < num; i++)
    {
        a[i].isfree = true;
        a[i].number = i + 1;
    }
}

int NumOfOcc()
{
    int c = 0;
    for (int i = 0; i < 10; i++)
    {
        if (!hotel[i].isfree)
            c++;
    }
    return c;
}

bool allocc()
{
    for (int i = 0; i < 10; i++)
        if (hotel[i].isfree)
            return false;
    if (k1 % 10 == 0 || k1 == NumOfOcc())
        return true;
}

DWORD WINAPI occupyRoom(PVOID pvParam)
{
    while (true)
    {
        WaitForSingleObject(hEventFree[ToOccupy], INFINITE);
        WaitForSingleObject(hMutex, INFINITE);
        if (k2 == 0)
        {
            return 0;
        }
        hotel[ToOccupy].isfree = false;
        cout << ToOccupy + 1 << " occ\n";
        ResetEvent(hEventFree[ToOccupy]);

        k2--;
        if (allocc() || k2 == 0) {
            SetEvent(hFull);
        }
        ToOccupy = (ToOccupy + 1) % n;
        ReleaseMutex(hMutex);
    }
    return 0;
}

DWORD WINAPI freeRoom(PVOID pvParam)
{
    while (true)
    {
        WaitForSingleObject(hShouldFree[ToFree], INFINITE);
        WaitForSingleObject(hMutex, INFINITE);
        if (k1 == 0)
            return 0;
        hotel[ToFree].isfree = true;
        ResetEvent(hShouldFree[ToFree]);
        SetEvent(hEventFree[ToFree]);
        k1--;
        cout << ToFree + 1 << " free\n";
        ToFree = (ToFree + 1) % n;
        ReleaseMutex(hMutex);
    }
    return 0;
}

void init_handles()
{
    string tmpstr = "";
    for (int i = 0; i < n; i++) {
        tmpstr = "Free" + char('0' + i);
        hEventFree[i] = CreateEventW(NULL, FALSE, TRUE,(LPCWSTR)tmpstr.c_str());
    }
    hMutex = CreateMutex(NULL, FALSE, (LPCSTR)"Mutex");
    hFull = CreateEventW(NULL, TRUE, FALSE, (LPCWSTR)"FULL");
    hShouldFree[0] = CreateEventW(NULL, TRUE, FALSE, (LPCWSTR)"PlsFree0");
    hShouldFree[1] = CreateEventW(NULL, TRUE, FALSE, (LPCWSTR)"PlsFree1");
    hShouldFree[2] = CreateEventW(NULL, TRUE, FALSE, (LPCWSTR)"PlsFree2");
    hShouldFree[3] = CreateEventW(NULL, TRUE, FALSE, (LPCWSTR)"PlsFree3");
    hShouldFree[4] = CreateEventW(NULL, TRUE, FALSE, (LPCWSTR)"PlsFree4");
    hShouldFree[5] = CreateEventW(NULL, TRUE, FALSE, (LPCWSTR)"PlsFree5");
    hShouldFree[6] = CreateEventW(NULL, TRUE, FALSE, (LPCWSTR)"PlsFree6");
    hShouldFree[7] = CreateEventW(NULL, TRUE, FALSE, (LPCWSTR)"PlsFree7");
    hShouldFree[8] = CreateEventW(NULL, TRUE, FALSE, (LPCWSTR)"PlsFree8");
    hShouldFree[9] = CreateEventW(NULL, TRUE, FALSE, (LPCWSTR)"PlsFree9");


}

int main()
{
init_hotel(hotel, 10);
init_handles();
HANDLE hStart = OpenEventW(EVENT_ALL_ACCESS, TRUE, (LPCWSTR) "START");
char c;
while (!hStart)
{
    cout << "Server is not enabled\n";
    cout << "Press esc to exit program of press any other key to try again\n";
    c = _getche();
    cout << endl;
    if (c == 27)
        return -1;
    hStart = OpenEventW(EVENT_ALL_ACCESS, TRUE, (LPCWSTR) "START");
}
HANDLE hWork = CreateEventW(NULL, TRUE, TRUE, (LPCWSTR) "WORK");
SetEvent(hStart);
CloseHandle(hStart);

cout << "Number of guests:";
cin >> k;
k2 = k1 = k;

int i;
int* x = new int[k << 1];
DWORD* dwThreadId = new DWORD[k << 1];
HANDLE* hThread = new HANDLE[k << 1];
for (i = 0; i< k; i++)
{
    x[i] = i;
    hThread[i] = CreateThread(NULL, 0, freeRoom, (PVOID)&x[i], 0, &dwThreadId[i]);
    if (!hThread) cout << "Free thread" << i << "not executed";
}
for (i = k; i< k << 1; i++)
{
    x[i] = i;
    hThread[i] = CreateThread(NULL, 0, occupyRoom, (PVOID)&x[i], 0, &dwThreadId[i]);
    if (!hThread) cout << "Occupy thread" << i << "not executed";
}


WaitForMultipleObjects(k << 1, hThread, TRUE, INFINITE);

for (int i = 0; i < n; i++) {
    CloseHandle(hEventFree[i]);
    CloseHandle(hShouldFree[i]);
}
CloseHandle(hFull);
CloseHandle(hMutex);
CloseHandle(hMutex);
CloseHandle(hWork);
delete x;
delete dwThreadId;
delete hThread;
return 0;

}

...