Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

Code to read: #include <stdio.h> #include <stdlib.h> #include <pthread.h> #inclu

ID: 3700705 • Letter: C

Question

Code to read:

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
#include <errno.h>

sem_t s1;
int c[2] = {0,0};

void *UpdateC1(void *arg)
{
   int i;
   for(i=0;i<1000000;i++)
   {
       sem_wait(&s1);
       c[0]=(c[0]+1)%2;
       c[1]=(c[1]+1)%2;
       sem_post(&s1);
   }
   return NULL;
}

void *UpdateC2(void *arg)
{
   int i;
   for(i=0;i<1000000;i++)
   {
       sem_wait(&s1);
       c[0]=(c[0]+1)%2;
       c[1]=(c[1]+1)%2;
       sem_post(&s1);
   }
   return NULL;
}

void *UpdateC3(void *arg)
{
   int i;
   for(i=0;i<1000000;i++)
   {
       sem_wait(&s1);
       c[0]=(c[0]+1)%2;
       c[1]=(c[1]+1)%2;
       sem_post(&s1);
   }
   return NULL;
}

int main(int argc, char *argv[])
{
   int rt,i;
   pthread_t t[3];

   if(sem_init(&s1, 0, 2)==-1)//Initialize the semaphore;
   {
       fprintf(stderr,"sem_init failed. errno=%d ",errno);
       exit(1);
   }
   rt=pthread_create( &t[0], NULL, &UpdateC1, NULL);
   if( rt!=0 )
       fprintf(stderr,"Thread %d creation failed: %d ", 0,rt);
   rt=pthread_create( &t[1], NULL, &UpdateC2, NULL);
   if( rt!=0 )
       fprintf(stderr,"Thread %d creation failed: %d ", 1,rt);
   rt=pthread_create( &t[2], NULL, &UpdateC3, NULL);
   if( rt!=0 )
       fprintf(stderr,"Thread %d creation failed: %d ", 2,rt);

   for(i=0;i<3;i++)
   {
       rt=pthread_join( t[i], NULL);
       if( rt!=0 )
           fprintf(stderr,"Wait for thread %d failed: %d ", i,rt);
   }

   printf (" %c %c ",'a'+c[0],'a'+c[1]);
   return 0;
}

2. Read given code RaceOrNot2.c and write all possible outputs of the program. Assume there will be no thread creation or joining failures or semaphore failures. If you believe there is only one possible output, you just need to write that output.

Explanation / Answer

One thing to start with is that semaphores are not locks, they are signalling mechanism.

sem_wait suspends the calling thread until the semaphore pointed to by sem has non-zero count. After that it decreases the semaphore count atomically.

On the contrary sem_post atomically increases the count of the semaphore sem. It is similar to saying "I am done you can carry on".

You are creating 3 threads each calling an action on the semaphore sem, which will effectively give us multiple answers.

The array c will take on multiple values. Possible values of c are {0,1}{0,0}{1,0}{1,1}.

So the possible outputs are :

1. a b

2. a a

3. b a

4. b b