1
  1. Why this code give me different outputs every time?
  2. Why it doesnt finish the loop?
  3. What should I do to make it finish the loop? (despite context switches)?
  4. Anything else I'm doing wrong?

Any help would be appreciated!

#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>
#define MAX 10

int buffer[MAX];
int fill = 0;
int use = 0;
int count = 0;

int loops = 15; 


void put(int value) {
    buffer[fill] = value;
    fill = (fill + 1) % MAX;
    count++;
    printf("putting %d\n", value);
}

int get() {
    int tmp = buffer[use];
    use = (use + 1) % MAX;
    count--;
    return tmp;
}

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t c_empty = PTHREAD_COND_INITIALIZER;
pthread_cond_t c_fill = PTHREAD_COND_INITIALIZER;

void *producer(void *arg) {
    printf("producer starts\n");
    int i;
    for (i = 0; i < loops; i++) {
        pthread_mutex_lock(&mutex); // p1
        while (count == MAX) // p2
            pthread_cond_wait(&c_empty, &mutex); // p3
        put(i); // p4
        pthread_cond_signal(&c_fill); // p5
        pthread_mutex_unlock(&mutex); // p6
    }
    return NULL;
}

void *consumer(void *arg) {
    printf("consumer starts\n");
    int i;
    for (i = 0; i < loops; i++) {
        pthread_mutex_lock(&mutex); // c1
        while (count == 0) // c2
            pthread_cond_wait(&c_fill, &mutex); // c3
        int tmp = get(); // c4
        pthread_cond_signal(&c_empty); // c5
        pthread_mutex_unlock(&mutex); // c6
        printf("consuming: %d\n", tmp);
    }
    return NULL;
}


int main(int argc, char *argv[]) {
    printf("parent: begin\n");
    pthread_t p, x;
    pthread_create(&p, NULL, producer, NULL);
    pthread_create(&x, NULL, consumer, NULL);


    printf("parent: end\n");
    return 0;
}

Makefile:

all: wcountb
wcountb: wcountb.c
    gcc -g -Wall -o wcountb wcountb.c -lpthread
user429864
  • 15
  • 3

1 Answers1

1

At the end of the main, you should call for pthread_join, like this:

  ...
  pthread_join(p, NULL);
  pthread_join(x, NULL);
  return 0;
}

Without that call, the threads are created and when you reach the end of main(), then your program terminates, thus your threads may be able to finish their job, or not, which explains the fact that sometimes your code works.

The pthread_join() function shall suspend execution of the calling thread until the target thread terminates, unless the target thread has already terminated.

Taken from the manual of pthread_join().

An almost related question lies here.

Community
  • 1
  • 1
gsamaras
  • 71,951
  • 46
  • 188
  • 305