I am facing a synchronisation or scheduling problem with threads. I have simplified my problem to the following one.
I have a producer thread that increases an integer value by one and a consumer thread that decreases the integer value by one too. Now because the integer is shared i need to use pthread mutex as shown in program below. If no signaling is used, that is no pthread_cond_t is used, I found out that the times the process stays in one thread, consumer or producer is not equal at all.
So, I thought that each time i produce something the consumer is called by a signal. However this method which is shown below, still writes in console values of 1600 by the producer. Clearly not a fair by the threads.
Question: how can i make this program fair, so that the value is "often" in a range of "0"? I have also tried to extend to extend the waiting time up to 1000. No difference.
Thanks
Code:
#include <stdio.h>
#include <pthread.h>
#include <signal.h>
#define MAXBUFFER 10
typedef struct share share_t;
struct share
{
pthread_mutex_t mutex;
int buff [MAXBUFFER];
int nput;
int nvalue;
};
share_t shared;
int runcond;
pthread_cond_t token_cond;
void sigfun(int sig)
{
runcond=0;
(void) signal (SIGINT, SIG_DFL);
}
void initialize_shared(void)
{
runcond=1;
pthread_mutex_init(&shared.mutex,NULL);
pthread_mutex_lock(&shared.mutex);
int i;
shared.nput=0;
shared.nvalue=0;
for (i=0;i<MAXBUFFER;i++)
{
shared.buff[i]=0;
}
pthread_mutex_unlock(&shared.mutex);
return;
}
void * produce ()
{
int i=0;
while (runcond){
pthread_mutex_lock(&shared.mutex);
shared.nput++;
if ((shared.nput % 10)==0)printf("Nput Producer %d\n",shared.nput);
pthread_cond_signal(&token_cond);
//pthread_cond_wait(&token_cond,&shared.mutex);
pthread_mutex_unlock(&shared.mutex);
}
pthread_exit(NULL);
}
void * consume ()
{
int i;
while (runcond){
pthread_mutex_lock(&shared.mutex);
pthread_cond_wait(&token_cond,&shared.mutex);
shared.nput--;
if ((shared.nput % 10)==0)printf("Nput Consumer %d\n",shared.nput);
//pthread_cond_signal(&token_cond);
pthread_mutex_unlock(&shared.mutex);
}
pthread_exit(NULL);
}
int main (void)
{
(void) signal (SIGINT, sigfun);
initialize_shared();
pthread_t producera;
pthread_t consumer;
int i;
pthread_mutex_lock(&shared.mutex);
pthread_create(&consumer,NULL,consume,NULL);
pthread_create(&producera,NULL,produce,NULL);
pthread_mutex_unlock(&shared.mutex);
wait(10);
pthread_mutex_lock(&shared.mutex);
runcond=0;
pthread_mutex_unlock(&shared.mutex);
pthread_join(consumer,NULL);
pthread_join(producera,NULL);
return 0;
}