lab4, producer/consumer fixed output

This commit is contained in:
2024-12-08 19:46:11 +02:00
parent c0670991b1
commit 9386abc939
5 changed files with 137 additions and 52 deletions

View File

@@ -7,6 +7,9 @@
#include "producer.h"
#include "consumer.h"
#include "reader_writer.h"
#include <fcntl.h>
std::atomic stopProduction(false);
[[noreturn]] void runSignalHandler() {
setupSignalHandlers();
@@ -17,33 +20,67 @@
}
void runProducerConsumer() {
Buffer buffer(10);
std::counting_semaphore<3> producerSem(3);
std::counting_semaphore<5> consumerSem(5);
const int NUM_PRODUCERS = 3;
const int NUM_CONSUMERS = 2;
std::vector<std::thread> producers;
std::vector<std::thread> consumers;
// Create pipe
int pipe_fd[2];
if (pipe(pipe_fd) == -1) {
std::cerr << "Pipe creation failed" << std::endl;
return;
}
for (int i = 0; i < 3; ++i) {
producers.emplace_back([i, &buffer, &producerSem]() {
const Producer producer(i, buffer, producerSem);
producer.run();
// Set pipe to non-blocking mode
int flags = fcntl(pipe_fd[1], F_GETFL, 0);
fcntl(pipe_fd[1], F_SETFL, flags | O_NONBLOCK);
// Create semaphores
std::counting_semaphore<3> producerSemaphore(3);
std::counting_semaphore<5> consumerSemaphore(5);
// Atomic flags for synchronization
std::atomic<bool> stopProduction(false);
std::atomic<int> itemsProduced(0);
std::atomic<int> itemsConsumed(0);
// Create threads
std::vector<std::thread> producerThreads;
std::vector<std::thread> consumerThreads;
// Create producer threads
for (int i = 0; i < NUM_PRODUCERS; ++i) {
producerThreads.emplace_back([&, i]() {
Producer producer(i, pipe_fd[1], producerSemaphore);
producer.run(itemsProduced, stopProduction);
});
}
for (int i = 0; i < 3; ++i) {
consumers.emplace_back([i, &buffer, &consumerSem]() {
const Consumer consumer(i, buffer, consumerSem);
consumer.run();
// Create consumer threads
for (int i = 0; i < NUM_CONSUMERS; ++i) {
consumerThreads.emplace_back([&, i]() {
Consumer consumer(i, pipe_fd[0], consumerSemaphore);
consumer.run(itemsConsumed, stopProduction);
});
}
for (auto& p : producers) {
p.join();
// Wait for producers to finish
for (auto& thread : producerThreads) {
thread.join();
}
for (auto& c : consumers) {
c.join();
// Signal stop and wait for consumers
stopProduction = true;
for (auto& thread : consumerThreads) {
thread.join();
}
// Close pipe
close(pipe_fd[0]);
close(pipe_fd[1]);
// Print final statistics
std::cout << "Total items produced: " << itemsProduced
<< "\nTotal items consumed: " << itemsConsumed << std::endl;
}
void runReaderWriter() {
@@ -74,7 +111,6 @@ int main() {
case 1:
std::cout << "Running Signal Handler...\n";
runSignalHandler();
break;
case 2:
std::cout << "Running Producer/Consumer...\n";
runProducerConsumer();