Multithreading bounded character buffer problem
- 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;
}