Unique type of producer consumer homework problem driving me nuts

Multithreading bounded character buffer problem

  1. The shared character buffer is filled with multiple characters at a time in the producer task
    2.The buffer gets read and emptied in the consumer task
    Help me with the thread sync, I am confused if I should use a cond variable or use multiple semaphores
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <semaphore.h>
#include <unistd.h>

#define SIZE 186

int min(int a, int b);
void process_data(char *buffer, int bufferSizeInBytes);
int get_external_data(char *buffer, int bufferSizeInBytes);

int get_external_data(char *buffer, int bufferSizeInBytes)
{
    int status;
    int val;
	char srcString[] = "0123456789abcdefghijklmnopqrstuvwxyxABCDEFGHIJKLMNOPQRSTUVWXYZ";

	val = (int)(random()%min(bufferSizeInBytes, 62));

	if (bufferSizeInBytes < val)
		return (-1);

	strncpy(buffer, srcString, val);

	return val;
}

void process_data(char *buffer, int bufferSizeInBytes)
{
    int i;
    if(buffer)
    {
		printf("thread %li - ", pthread_self());
		for(i=0; i<bufferSizeInBytes; i++)
		{
			printf("%c", buffer[i]);
		}
		printf("\n");
		memset(buffer, 0, bufferSizeInBytes);
    }
	else
		printf("error in process data - %li\n", pthread_self());

    return;
}


//TODO Define global data structures to be used 
char data[SIZE];//since it is a character the SIZE value is same as the buffer_size_in_bytes ie. 1 char = 1 byte
int d_received,d_total; 
pthread_mutex_t lock,i_lock;
int flag = 0;
sem_t sem_empty, sem_full;
int min(int a,int b)
{
    if(a<b)
    return a;
    else
    return b;
}
void init()
{
    d_received=0;
    d_total=0;
    memset(data,0,SIZE);//initializing the buffer with 0;
    pthread_mutex_init(&lock,NULL);
    pthread_mutex_init(&i_lock,NULL);
    sem_init(&sem_empty,0,1);
    sem_init(&sem_full,0,1);
}
/**
 * This thread is responsible for pulling data off of the shared data
 * area and processing it using the process_data() API.
 */
void *reader_thread(void *arg) {
	//TODO: Define set-up required
	
    
	while(1) {
	    
		//TODO: Define data extraction (queue) and processing
	       pthread_mutex_lock(&lock);
	       if(flag == 1)
	       {
	            pthread_yeild();
	        }
	        if(d_total == 0)
	        {
                //sem_wait(&sem_empty);
                flag = 1;
	            pthread_mutex_unlock(&lock);
	        }pthread_mutex_lock(&lock);
		    process_data(data,d_total);
		    d_total = 0;
		    sem_post(&sem_full);
		    pthread_mutex_unlock(&lock);
		        
	}
    
	return NULL;
}


/**
 * This thread is responsible for pulling data from a device using
 * the get_external_data() API and placing it into a shared area
 * for later processing by one of the reader threads.
 */
void *writer_thread(void *arg) {
	//TODO: Define set-up required
	
      
	while(1) {
		//TODO: Define data extraction (device) and storage

		    
		    if(d_total>=SIZE)
		    {
                sem_wait(&sem_full);
               // pthread_mutex_unlock(&lock);
		    }pthread_mutex_lock(&lock);
		    d_received=get_external_data(data,SIZE-d_total);
		    d_total += d_received;
		    sem_post(&sem_empty);
		    pthread_mutex_unlock(&lock);
		    
	}
    
	return NULL;
}


#define M 10
#define N 20
int main(int argc, char **argv) {
	int i;
	init();

    pthread_t th1[M];
    pthread_t th2[N];
	for(i = 0; i < N; i++) {
		if(pthread_create(&th1[i], NULL, &reader_thread, NULL)!=0)
		perror("Failed to create thread:");
	}

	for(i = 0; i < M; i++) {
	   	if(pthread_create(&th2[i], NULL, &writer_thread, NULL)!=0);
	   	perror("Failed to create thread:");
	}

    for(i = 0; i < N; i++) {
		pthread_join(th1[i],NULL);
	}

	for(i = 0; i < M; i++) {
		pthread_join(th2[i],NULL);
	}
    sem_destroy(&sem_empty);
    sem_destroy(&sem_full);
    pthread_mutex_destroy(&lock);
    pthread_mutex_destroy(&i_lock);
	return 0;
}                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    

@hybridpriest , hello and welcome. we are not here to do your homework for you but can point you towards resources that can help you solve the challenge. There are many example pthread programs online, I recommend you go there first, type pthread synchronisation examples or similar into your favourite search engine and see what comes back, read/copy/try a few online examples and if you are still unable to solve then come back - showing the code you have written, the tests you have tried and the outputs of those and we can review the situation. Here's one link to start you off pthread sync example

1 Like