проблема.У меня есть отель на 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;
}