Salve a tutti,sperò qualcuno sia disposto ad aiutarmi,sto sbattendo la testa con i magnifici puntatori.
Per l' università(Uninettuno) sto seguendo un corso in cui ,tra le molte cose,c'è il multithreading in C++11.
Mi sto esercitando sul problema del produttore/consumatore ma ho incontrato delle difficoltà quando il buffer invece di contenere una coda di interi contiene una coda di msg_t, dove rappresenta una classe apposita presente nell' esercizio.
#ifndef HOMEWORK_1_MSG_T_H
#define HOMEWORK_1_MSG_T_H
class msg_t{
public:
msg_t();
msg_t *msg_init(void *content_);
void msg_destroy(msg_t *msg);
void *content;
};
#endif //HOMEWORK_1_MSG_T_H
#include "msg_t.h"
msg_t::msg_t() : content(nullptr) {}
msg_t* msg_t::msg_init(void *content_) {
content=content_;
return static_cast<msg_t *>(content);
}
void msg_t::msg_destroy(msg_t *msg){
content=msg;
delete content;
content= nullptr;
}
#ifndef HOMEWORK_1_BUFFER_T_H
#define HOMEWORK_1_BUFFER_T_H
#include <queue>
#include <mutex>
#include <condition_variable>
#include "msg_t.h"
#define BUFFER_ERROR (msg_t *) NULL
class buffer_t{
public:
buffer_t* buffer_init(unsigned int maxsize);
void put_bloccante(buffer_t* buffer, msg_t *msg);
msg_t* get_bloccante(buffer_t* buffer);
private:
unsigned int maxSize;
std::queue<msg_t> messages; //coda di messaggi condivisa
std::mutex mtx; //Mutex per garantire l'accesso esclusivo alla coda
std::condition_variable bufferNotEmpty;
std::condition_variable bufferNotFull;
};
buffer_t* buffer_t::buffer_init(unsigned int maxsize){
(this)->maxSize=maxsize;
return this;
}
void buffer_t::put_bloccante(buffer_t *buffer, msg_t *msg) {
try {
std::unique_lock<std::mutex> lock(mtx);
bufferNotFull.wait(lock,[&buffer]{return buffer->messages.size() < (buffer)->maxSize;});
(buffer)->messages.push(*msg);
bufferNotEmpty.notify_all(); // Notifica i consumatori che il buffer non è vuoto
lock.unlock();
//msg->msg_destroy(msg);
}
catch(const std::exception& e){
std::cerr << "An exception occurred: " << e.what() << std::endl;
}
}
msg_t* buffer_t::get_bloccante(buffer_t* buffer){
try {
std::unique_lock<std::mutex> lock(mtx);
bufferNotEmpty.wait(lock, [&buffer] { return !buffer->messages.empty(); }); // Attende finché il buffer non è vuoto
msg_t *message=new msg_t();
*message = (buffer)->messages.front();
(buffer)->messages.pop();
bufferNotFull.notify_all();
lock.unlock();
//message.msg_destroy(&message);
return message;
}
catch(const std::exception& e){
std::cerr << "An exception occurred: " << e.what() << std::endl;
return nullptr;
}
}
#include <iostream>
#include <thread>
#include "buffer_t.h"
void producer(buffer_t& buffer, int producer_id);
void consumer(buffer_t& buffer, int consumer_id);
int main() {
buffer_t *buffer=new buffer_t();
buffer->buffer_init(10);
std::thread producers(producer,std::ref(*buffer),1);
std::thread consumers(consumer,std::ref(*buffer),1);
producers.join();
consumers.join();
return 0;
}
void producer(buffer_t& buffer, int producer_id) {
try {
for (int i = 0; i < 10; i++) {
msg_t* message=new msg_t();
message->msg_init(&i);
buffer.put_bloccante(&buffer, message);
int* contentPtr = static_cast<int*>(message->content);
int contentValue = *contentPtr;
std::cout << "\nProducer " << producer_id << " pushed message -->" <<contentValue<< std::endl;
delete message;
}
}
catch (const std::exception& e) {
std::cerr << "producer " << producer_id << " encountered an exception: " << e.what() << std::endl;
}
}
void consumer(buffer_t& buffer, int consumer_id) {
for (int i = 0; i < 10; i++) {
try {
msg_t* message=new msg_t();
message = buffer.get_bloccante(&buffer);
int* contentPtr = static_cast<int*>(message->content);
int contentValue = *contentPtr;
std::cout << "\nConsumer " << consumer_id << " popped message -->" <<contentValue<< std::endl;
delete message;
} catch (const std::exception& e) {
std::cerr << "Consumer " << consumer_id << " encountered an exception: " << e.what() << std::endl;
}
}
}
Al momento per semplicità ho creato solo un produttore e un consumatore,con un biffer che contiene una oda di messaggi di tipo msg_t,ma succedono cose strane quando mangia e ? termina con errore.