Fork/Join Problem

Incorrect Implementation

pthread_cond_t  c = PTHREAD_COND_INITIALIZER;
pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER;
int done = 0;

void *child(void *arg) {
    printf("child\n");
    sleep(1);
    Mutex_lock(&m);
    done = 1;
    Cond_signal(&c);
    Mutex_unlock(&m);
    return NULL;
}
int main(int argc, char *argv[]) {
    pthread_t p;
    printf("parent: begin\n");
    Pthread_create(&p, NULL, child, NULL);
    Mutex_lock(&m);
    while (done == 0)
	Cond_wait(&c, &m); // releases lock when going to sleep
    Mutex_unlock(&m);
    printf("parent: end\n");
    return 0;
}
  • Issue: After line 19, switch to child, parent wait inf

Correct Implementation

pthread_cond_t  c = PTHREAD_COND_INITIALIZER;
pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER;
int done = 0;

void *child(void *arg) {
    printf("child\n");
    sleep(1);
    Mutex_lock(&m);
    done = 1;
    Cond_signal(&c);
    Mutex_unlock(&m);
    return NULL;
}
int main(int argc, char *argv[]) {
    pthread_t p;
    printf("parent: begin\n");
    Pthread_create(&p, NULL, child, NULL);
    Mutex_lock(&m);
    while (done == 0)
	Cond_wait(&c, &m); // releases lock when going to sleep
    Mutex_unlock(&m);
    printf("parent: end\n");
    return 0;
}

Producer/Consumer Problem (Bounded Buffer)

  • Producer threads
  • Consumer threads
  • Share a fixed size (bounded) queue
  • Worries: Atomicity of the queue, Ordering
  • Example:
    • unix pipe
    • $ cat file.txt | wc -l
    • cat fill queue, wc consume
    • need bound to limit memory

Solution V1 Issue

Consumer1Consumer2Producer
c1
c2
c3 (wait)
c1
c2
c3 (wait)
p1
p2
p4
READYp5 (signal)
p6
p1
p2
p3 (wait)
c2
c4
c5READY (BAD)
c6
c2
c3 (Wait, Stuck)

Solution V2 Issue

Consumer1Consumer2Producer
c1
c2
c3 (wait)
p1
p2
p4
READYp5 (signal)
p6
c1
c2
c4 (get)
c5
c6
c4 (BUG, get empty)