-9

I'm starting with threads and I'm having some problems resolving this:

This program produces an ordered sequence of number and second task reads them and prints them on the screen. How do I repair this to work as required?

Expected Output:

Consumed item: 1
Consumed item: 2
Consumed item: 3
Consumed item: 4
Consumed item: 5
Consumed item: 6

Actual Output:

Consumed item: 1
Consumed item: 4
Consumed item: 7
Consumed item: 10
Consumed item: 11
Consumed item: 14

The program:

#include <stdio.h>
#include <pthread.h>
#include <time.h>

#define          NBUFFERS       2

int item, in=0, out=0;
int buffer[NBUFFERS];
int stop =0; 

void *ProducerTask(void *data) //This is the producer task
{
     int nextp = 0;
     struct timespec mytime;
     mytime.tv_sec = 0;
     mytime.tv_nsec = 200000000;

     while (!stop) {
          nanosleep(&mytime, NULL);
          nextp++;
          buffer[in] = nextp;   /* produce a new item */
          in = (in + 1) % NBUFFERS;
     }
     pthread_exit(0);
}

void *ConsumerTask(void *data)
{
     int nextc;
     struct timespec mytime;
     mytime.tv_sec = 0;
     mytime.tv_nsec = 500000000;

     while (!stop) {
          nanosleep(&mytime, NULL);
          nextc = buffer[out];  /* consume a item */
          out = (out + 1) % NBUFFERS;
          printf("Consumed item: %d\n", nextc);
     }
     pthread_exit(0);
}

void *MonitorTask (void *data) //This is the monitor task
{
     getchar();
     stop = 1;
     pthread_exit(0);
}

void main(void)
{
     pthread_t task1;
     pthread_t task2;
     pthread_t task3;

     pthread_create (&task1, NULL, ProducerTask, NULL);
     pthread_create (&task2, NULL, ConsumerTask, NULL);
     pthread_create (&task3, NULL, MonitorTask, NULL);

     pthread_join(task1,NULL);
     pthread_join(task2,NULL);
     pthread_join(task3,NULL);

     printf("Main program exiting.\n");
}
Peter Wood
  • 23,859
  • 5
  • 60
  • 99
dani
  • 341
  • 1
  • 7
  • 18
  • 3
    "Fix this program" is definitely not a nice way of describing your problem. You need to correctly pinpoint and describe your problem to get good responses – Pavan Manjunath Apr 19 '12 at 06:40
  • 1
    What's the expected outcome (or output) and what's the actual? In other words, what's your problem? – Some programmer dude Apr 19 '12 at 06:41
  • Output: Consumed item: 1 Consumed item: 4 Consumed item: 7 Consumed item: 10 Consumed item: 11 Consumed item: 14 – dani Apr 19 '12 at 06:42
  • and should be :Consumed item: 1 Consumed item: 2 Consumed item: 3 Consumed item: 4 Consumed item: 5 Consumed item: 6 – dani Apr 19 '12 at 06:43
  • 1
    Why do you expect the o/p in that order? The threads are allowed to run in any order as they get scheduled, You are not providing any synchronization which makes them follow the order you desire. – Alok Save Apr 19 '12 at 06:45
  • @PavanManjunath We've fixed the question instead. – Peter Wood Apr 19 '12 at 06:55

2 Answers2

3
int buffer[NBUFFERS];
int stop =0; 

are global and accessed from multiple threads, they dont have any synchronization.
The race condition that follows is a problem if not the problem.

The boldened inline links should give you atleast an headstart in what you are doing wrong.

Alok Save
  • 202,538
  • 53
  • 430
  • 533
  • This is probably helpful too: [Accessing global variables in pthreads in different c files](http://stackoverflow.com/questions/7382636/accessing-global-variables-in-pthreads-in-different-c-files) – nacho4d Apr 19 '12 at 06:45
2

Shared resources need at least locking and passing data is usually solved with thread communication via condition variables see this example (C++, but it shows my point).

Edit: in this case the strange output is due to the fact that you use a small buffer in combination with a slower consumer than producer.

stefaanv
  • 14,072
  • 2
  • 31
  • 53