icp/oer/courses/c-advanced/sections/02-basic-algorithms/01_producer_consumer/program.c

93 lines
1.7 KiB
C

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <pthread.h>
typedef struct node
{
int Value;
struct node *Next;
}node;
typedef struct
{
node *Head;
node *Tail;
pthread_mutex_t Mutex;
}queue;
node *alloc_node(int Value, node *Next)
{
node *NewNode = malloc(sizeof(node));
NewNode->Value = Value;
NewNode->Next = Next;
return NewNode;
}
// NOTE: we are not going to talk about threads.
// the lock and unlock functions prevent the threads to execute the locked part at the same time,
// which could lead to errors
void enqueue(queue *Queue, int Value)
{
node *NewNode = alloc_node(Value, 0);
pthread_mutex_lock(&Queue->Mutex);
if(Queue->Tail)
Queue->Tail->Next = NewNode;
Queue->Tail = NewNode;
if(!Queue->Head)
{
Queue->Head = NewNode;
}
pthread_mutex_unlock(&Queue->Mutex);
}
int dequeue(queue *Queue)
{
pthread_mutex_lock(&Queue->Mutex);
node *First = Queue->Head;
int Result = First->Value;
Queue->Head = First->Next;
free(First);
pthread_mutex_unlock(&Queue->Mutex);
return Result;
}
node *peak(queue *Queue)
{
return Queue->Head;
}
queue CommunicationQueue;
void *Producer_Proc(void *ptr)
{
int Seed = atoi((char *)ptr);
srand(Seed);
for (int i = 0; i < 100; i ++)
{
enqueue(&CommunicationQueue, (rand()%10)+1);
}
return 0;
}
int main(int argc, char **argv)
{
CommunicationQueue.Head = 0;
CommunicationQueue.Tail = 0;
pthread_mutex_init(&CommunicationQueue.Mutex,0);
pthread_t Producer;
pthread_create(&Producer, 0, Producer_Proc, (void *)argv[1]);
// TODO: print 50 times the sum of the last two numbers from the queue
// don't forget to check if there is even anything on the queue
pthread_join(Producer, 0);
return 0;
}