141 lines
3.3 KiB
C
141 lines
3.3 KiB
C
/* ************************************************************************** */
|
|
/* */
|
|
/* ::: :::::::: */
|
|
/* producer_consumer.c :+: :+: :+: */
|
|
/* +:+ +:+ +:+ */
|
|
/* By: ruiferna <ruiferna@student.42porto.com> +#+ +:+ +#+ */
|
|
/* +#+#+#+#+#+ +#+ */
|
|
/* Created: 2025/10/07 22:17:29 by ruiferna #+# #+# */
|
|
/* Updated: 2025/10/08 18:38:50 by ruiferna ### ########.fr */
|
|
/* */
|
|
/* ************************************************************************** */
|
|
|
|
#include <pthread.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <unistd.h>
|
|
#include <sys/time.h>
|
|
|
|
#define BUFFER_SIZE 100
|
|
#define NUM_PRODUCERS 2
|
|
#define NUM_CONSUMERS 2
|
|
#define ITEMS_TO_PRODUCE 100
|
|
|
|
typedef struct s_buffer
|
|
{
|
|
int items[BUFFER_SIZE];
|
|
int count;
|
|
int in;
|
|
int out;
|
|
int produced_count;
|
|
pthread_mutex_t mutex;
|
|
} t_buffer;
|
|
|
|
|
|
long get_time(void)
|
|
{
|
|
struct timeval tv;
|
|
|
|
gettimeofday(&tv, NULL);
|
|
return ((tv.tv_sec * 1000) + (tv.tv_usec / 1000));
|
|
}
|
|
|
|
void *producer(void *arg)
|
|
{
|
|
t_buffer *buffer;
|
|
int item;
|
|
|
|
buffer = (t_buffer *)arg;
|
|
while (1)
|
|
{
|
|
pthread_mutex_lock(&buffer->mutex);
|
|
if (buffer->count < BUFFER_SIZE)
|
|
{
|
|
if (buffer->produced_count >= ITEMS_TO_PRODUCE)
|
|
{
|
|
pthread_mutex_unlock(&buffer->mutex);
|
|
break ;
|
|
}
|
|
buffer->produced_count++;
|
|
item = buffer->produced_count;
|
|
buffer->items[buffer->in] = item;
|
|
buffer->in = (buffer->in + 1) % BUFFER_SIZE;
|
|
buffer->count++;
|
|
printf("%ldms - Producer produced item: %d\n", get_time(), item);
|
|
pthread_mutex_unlock(&buffer->mutex);
|
|
}
|
|
else
|
|
{
|
|
pthread_mutex_unlock(&buffer->mutex);
|
|
usleep(100);
|
|
}
|
|
}
|
|
return (NULL);
|
|
}
|
|
|
|
void *consumer(void *arg)
|
|
{
|
|
t_buffer *buffer;
|
|
int item;
|
|
|
|
buffer = (t_buffer *)arg;
|
|
while (1)
|
|
{
|
|
pthread_mutex_lock(&buffer->mutex);
|
|
if (buffer->count > 0)
|
|
{
|
|
item = buffer->items[buffer->out];
|
|
buffer->out = (buffer->out + 1) % BUFFER_SIZE;
|
|
buffer->count--;
|
|
printf("%ldms - Consumer consumed item: %d\n", get_time(), item);
|
|
pthread_mutex_unlock(&buffer->mutex);
|
|
}
|
|
else
|
|
{
|
|
if (buffer->produced_count >= ITEMS_TO_PRODUCE)
|
|
{
|
|
pthread_mutex_unlock(&buffer->mutex);
|
|
break ;
|
|
}
|
|
pthread_mutex_unlock(&buffer->mutex);
|
|
usleep(100);
|
|
}
|
|
}
|
|
return (NULL);
|
|
}
|
|
|
|
int main(void)
|
|
{
|
|
pthread_t producers[NUM_PRODUCERS];
|
|
pthread_t consumers[NUM_CONSUMERS];
|
|
t_buffer *buffer;
|
|
int i;
|
|
|
|
buffer = malloc(sizeof(t_buffer));
|
|
if (!buffer)
|
|
return (1);
|
|
buffer->count = 0;
|
|
buffer->in = 0;
|
|
buffer->out = 0;
|
|
buffer->produced_count = 0;
|
|
pthread_mutex_init(&buffer->mutex, NULL);
|
|
|
|
i = -1;
|
|
while (++i < NUM_PRODUCERS)
|
|
pthread_create(&producers[i], NULL, producer, buffer);
|
|
i = -1;
|
|
while (++i < NUM_CONSUMERS)
|
|
pthread_create(&consumers[i], NULL, consumer, buffer);
|
|
|
|
i = -1;
|
|
while (++i < NUM_PRODUCERS)
|
|
pthread_join(producers[i], NULL);
|
|
i = -1;
|
|
while (++i < NUM_CONSUMERS)
|
|
pthread_join(consumers[i], NULL);
|
|
|
|
pthread_mutex_destroy(&buffer->mutex);
|
|
free(buffer);
|
|
return (0);
|
|
}
|