race condition during termination process



Have you ever heard about lupg's multithread tutorials?

This is the tutorial's URL:
http://users.actcom.co.il/~choo/lupg/tutorials/multi-thread/multi-thread.html

There are 2 exercise at the last part of chapter 7.7(Threads
Cancellation - A Complete Example) of that tutorial.

The first exercise is:

Exercise: Our Last Program contains some possible race condition during
its termination process. Can you see what this race is all about? Can
you offer a complete solution to this problem? (hint - think of what
happens to threads deleted using 'delete_handler_thread()').

But I couldn't find the cause of race condition and the solution.

Following program is basically almost same as "Their Last Program":

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

#define LOOP_COUNT 600

pthread_mutex_t lock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
pthread_cond_t radio = PTHREAD_COND_INITIALIZER;

int request_finished = 0;

/* The count of requests that worker thread handled. */
int request_index;

/* The count of requests that main thread made. */
int request_count;

void
cleanup_thr(void *arg)
{
pthread_mutex_unlock(&lock);
}

void*
construct_thr(void *arg)
{
pthread_cleanup_push(cleanup_thr, arg);

pthread_mutex_lock(&lock);

while (1) {

/* If there is any request not yet handled, */
if (request_index < request_count) {
request_index++;
}
else {
/* If there are no more newly created requests */
if (request_finished) {
pthread_mutex_unlock(&lock);
pthread_exit(NULL);
}
else {
pthread_cond_wait(&radio, &lock);
}
}
}

/* Never reached */
pthread_mutex_unlock(&lock);

pthread_cleanup_pop(0);

return (void *) NULL;
}

int
main()
{
int i, j, k;
int thr_id[LOOP_COUNT];
pthread_t thr_pool[LOOP_COUNT];
void *rv;

for (i = 0, j = 0, k = 0; i < LOOP_COUNT; i++) {

/* Make requests as many as LOOP_COUNT */
pthread_mutex_lock(&lock);
request_count++;
pthread_cond_signal(&radio);
pthread_mutex_unlock(&lock);

/* Cancel the oldest thread */
/* Cancellation is done by 2% chance of the time */
if (rand() % 100 < 2) {
if (k < j) {
pthread_cancel(thr_pool[k++]);
}
}

/* Create thread */
/* Creation is done by 5% chance of the time */
if (rand() % 100 < 5) {
thr_id[j] = j;
pthread_create(&thr_pool[j], NULL, construct_thr, (void *)
&thr_id[j]);
j++;
}
}

/* Notify all threads that there are "No More Newly created
Requests" */
pthread_mutex_lock(&lock);
request_finished = 1;
pthread_cond_broadcast(&radio);
pthread_mutex_unlock(&lock);

/* Waiting for each thread exiting */
for (i = k; i < j; i++) {

pthread_join(thr_pool[i], &rv);

/* But, pthread_join() never returns. */
/* Some threads never wake up! */
/* Is this race condition? */
/* Is it related with pthread_cancel() -- as lupg tutorial's hint
said? */
}

return 0;
}

.



Relevant Pages

  • Re: race condition during termination process
    ... There are 2 exercise at the last part of chapter 7.7(Threads ... But I couldn't find the cause of race condition and the solution. ... int request_index; ...
    (comp.programming.threads)
  • K&R2 1-23
    ... The exercise is to remove all comments from a source file. ... void strconst; ... int main ...
    (comp.lang.c)
  • Re: K&R2 1-23
    ... > The exercise is to remove all comments from a source file. ... > void strconst; ... > int main ...
    (comp.lang.c)
  • Help in Java swings(internal Frame)
    ... public int getSize() ... public void valueChanged{ ... private JScrollPane scrollPane1; ... public class PeakContainer extends JInternalFrame ...
    (comp.lang.java.programmer)
  • [PATCH] get rid if __cpuinit and __cpuexit
    ... unsigned long action, void *hcpu) ... unsigned int cpu = hcpu; ... -static int __cpuinit ... __cpu_up(unsigned int cpu) ...
    (Linux-Kernel)