Я написал этот код, который имитирует систему парковки, однако у меня возникает проблема, когда мне приходится повторно использовать структуру, содержащую messageQueue, для моей корзины. Проблема возникает, когда я пытаюсь связаться с обработчиком для выхода с ID_CAR_IND. Структура отправляется как сообщение, поэтому я подозреваю, что оно удаляется до прибытия, но я не могу понять, что происходит, и где оно идет не так. Следует отметить, что реализация требования - использование pthread и создание 3 потоков.
#include <iostream>
#include <pthread.h>
#include <stdlib.h>
#include <queue>
#include <time.h>
#include <unistd.h>
#include "Message.h"
#include "MsgQueue.h"
using namespace std;
enum{
ID_START_IND,
ID_ENTRY_REQ,
ID_ENTRY_CFM,
ID_CAR_IND,
ID_STAY_HERE,
ID_EXIT_REQ,
ID_EXIT_OUT,
ID_EXIT_CFM
};
//MESSAGES
struct Car : public Message
{
Car(int carID, MsgQueue* queue) : id(carID), carmq(queue){}
MsgQueue *carmq;
int id;
};
struct OpenReq : public Message
{
MsgQueue *Who_is_asking_;
};
struct CloseReq : public Message
{
MsgQueue *Who_is_asking_exit;
};
struct EntryDoorOpen : public Message{
bool result;
};
MsgQueue entryMq(20);
MsgQueue exitMq(20);
void carHandler(Car* car, unsigned id, Message* msg){
switch(id){
case ID_START_IND:
{
cout << "car " << car->id << " wants to enter" << endl;
OpenReq * req = new OpenReq();
req->Who_is_asking_ = car->carmq;
entryMq.send(ID_ENTRY_REQ, req);
}
break;
case ID_ENTRY_CFM:
{
cout << "car " << car->id << " entered parking" << endl;
entryMq.send(ID_CAR_IND);
}
break;
case ID_STAY_HERE:
{
}
break;
case ID_EXIT_CFM:
{
cout << "car " << car->id << "Left parking" << endl;
exitMq.send(ID_EXIT_OUT);
}
break;
default:
break;
}
}
void entryHandler(unsigned id, Message* msg){
OpenReq* req=static_cast<OpenReq*>(msg);
switch(id){
case ID_ENTRY_REQ:
{
cout << "Access granted. Opening entry door " << endl;
req->Who_is_asking_->send(ID_ENTRY_CFM);
}
break;
case ID_CAR_IND:
{
cout << "Closing entry door " << endl;
sleep(2);
req->Who_is_asking_->send(ID_EXIT_REQ);
}
break;
default:
break;
}
}
void exitHandler(unsigned id, Message * msg)
{
OpenReq* req = static_cast<OpenReq*>(msg);
switch(id)
{
case ID_EXIT_REQ:
{
cout << "Leaving is Granted. Opening exit door" << endl;
req->Who_is_asking_->send(ID_EXIT_CFM);
}
break;
case ID_EXIT_OUT:
{
cout << "Car has left the parkinglot" << endl;
}
break;
default:
break;
}
}
void *car(void* data){
Car *car = static_cast<Car*>(data);
car->carmq->send(ID_START_IND);
for(;;){
unsigned long id;
Message *msg = car->carmq->receive(id);
carHandler(car,id,msg);
delete(msg);
}
}
void *entry(void* data){
for(;;){
unsigned long id;
Message *msg = entryMq.receive(id);
entryHandler(id,msg);
delete(msg);
}
}
void *exit(void * data){
for(;;){
unsigned long id;
Message *msg = exitMq.receive(id);
exitHandler(id,msg);
delete(msg);
}
}
int main()
{
MsgQueue q(10);
Car carObj(1, &q);
pthread_t carThread, entryThread;
pthread_create(&carThread,nullptr,car, &carObj);
pthread_create(&entryThread,nullptr,entry, nullptr);
pthread_join(carThread,nullptr);
return 0;
}
//
// Created by stud on 11/3/19.
//
#include "MsgQueue.h"
#include "Message.h"
#include <iostream>
MsgQueue::MsgQueue(unsigned long maxSize) : maxSize_(maxSize)
{
//Init pthread funktionerne.
pthread_mutex_init(&msgmutex, NULL);
pthread_cond_init(&msgcond,NULL);
};
void MsgQueue::send(unsigned long id, Message* msg)
{
pthread_mutex_lock(&msgmutex);
while(msgqueue_.size() == maxSize_)
{
pthread_cond_wait(&msgcond, &msgmutex);
}
info besked;
besked.id = id;
besked.msg = msg;
msgqueue_.push(besked);
pthread_cond_broadcast(&msgcond);
pthread_mutex_unlock(&msgmutex);
//std::cout << "sending from id #" << id << std::endl;
};
Message* MsgQueue::receive(unsigned long&id)
{
pthread_mutex_lock(&msgmutex);
while(msgqueue_.empty())
{
pthread_cond_wait(&msgcond,&msgmutex);
}
info besked;
besked = msgqueue_.front();
id = besked.id;
msgqueue_.pop();
pthread_cond_broadcast(&msgcond);
pthread_mutex_unlock(&msgmutex);
return besked.msg;
};
MsgQueue::~MsgQueue()
{
pthread_mutex_destroy(&msgmutex);
pthread_cond_destroy(&msgcond);
};
//
// Created by stud on 11/3/19.
//
#pragma once
#include <iostream>
#include <pthread.h>
#include "Message.h"
#include <queue>
struct info : public Message
{
unsigned long id;
Message* msg;
};
class MsgQueue
{
public:
MsgQueue(unsigned long maxSize);
void send(unsigned long id, Message* msg = NULL);
Message* receive(unsigned long&id);
~MsgQueue();
private:
unsigned long maxSize_;
std::queue <info> msgqueue_;
pthread_cond_t msgcond;
pthread_mutex_t msgmutex;
};
//
//
//
#pragma once
class Message
{
public:
virtual ~Message(){};
};