POSIX - Hot to check if detached thread is still active

Hello,

I have created program that run threads one by one, maximum 100. Each thread will process one block of data, and once it`s finished, new thread is created with new block of data....etc

I have array of values to control status of each thread, like this:

array_thread_status[0]=1
array_thread_status[1]=0
array_thread_status[2]=0
array_thread_status[3]=1
...
array_thread_status[99]=1

When thread is created value is set to 1. When thread is finished, it set value to 0, so main program can create new thread instead.

This is all working good, so far...but I`m affraid of this scenario:

Main program
CREATE THREAD
SET VALUE TO 1

Thread
STARTING THREAD
PROBLEM - THREAD IS TERMINATED AND DIDN`T RESET VARIABLE TO 0

Main program might think that thread is still active, and new one will not be run.

So, I think that there must be another way to check weather thread is still active or not.

Try pthread_join

it`s detached thread

How are you creating the detached threads ... please show your code.

/Mark it active/
active_status_array[i]=1;

   /*Create new threads*/
   rc = pthread_create\(&thdreads[i], &attr, file_parser, \(void*\)&thread\_data_array[i]\);

   if \(rc\)
   \{
      printf\("ERROR; return code from pthread_create\(\) is %d INDEX %d\\n", rc,i\);
      exit\(-1\);
   \}
   else
   \{
        /*Deatach thread*/
        rc = pthread_detach\(thdreads[i]\);
        if \(rc\) \{
          printf\("Got an unexpected result! rc=%d\\n",rc\);
          exit\(-1\);
         \}

   \}

Also, one more problem with join is that if I have 100 threads, and if they are all working and I start join wait on first one which is wait 5 min, for example. during that time other might be free...so that could slow down entire program.

My main program never ends, it`s always iteratting trought the loop and checking for free space to create new threads.

I think you have a need for synchronization - meaning you do not want detached threads.

Here's why - On most systems the "thread" is really a part of the parent process - linux is an exception. This means generally there isn't a simple way to tell if a thread has terminated. If you need to know the status of a thread then you need synchronization.
Correct me where I misunderstand.

Otherwise, detached threads run whether or not the previous thread completed or not.
This is the exact opposite of synchronization.

What type of synchronization do you suggest?

I would like to remind you that if thread is terminated due some problem (memory or something like that) synchronization might fail as well.

Also, if I use phtread_join, after thread is terminated, resources will still be occupied until main program is finished.
Since my program is in the endless loop I decide to use detached threads, in order to free resources and make room for new ones.

I'm suggesting that you consider at least something like a shared memory array instead of an internal array, so you have to have a way to communicate. Assuming you need to track what is going on. You can create non-detached threads and still not have to call pthread_join until you know the thread has ended.

Include some timing component in the array - a start time in epoch seconds maybe.
After some ridiculous amount of time has elapsed, like 30 minutes, call pthread_cancel on the offending thread_id. Then open up the slot for reuse.

If threads are dumping core or corrupting memory then this will not fix the problem.
Only code changes can fix that.

The normal threaded way to do what is suggested is to create a monitor thread for notification and use pthread_cond primitives for the synchronization.
Example code follows.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <unistd.h>
#include <time.h>

#define MAXTHREAD 5
#define FIRE 20

typedef struct msg {
pthread_t tnum;
} M;

/*global*/
pthread_cond_t alert = PTHREAD_COND_INITIALIZER;
pthread_mutex_t alertmtx = PTHREAD_MUTEX_INITIALIZER;
static M foo;
void *monitor(void *);
void *do_random(void *);

#define liveloop() {while (1) {sleep(1);}}

int main(void) {
int y = 0;
pthread_t monthread;
pthread_t t[MAXTHREAD];

                       srand(time(NULL));
                       if (pthread_create(&monthread,NULL,monitor,NULL) != 0) {perror("pthread_create()"); return -1;}
                       while (y < MAXTHREAD) {
                                             pthread_create(&t[y],NULL,do_random,NULL);
                                             y++;
                       }
                       liveloop();
}

 void *monitor(void *arg) {

               pthread_mutex_lock(&alertmtx);
               while (1) {
                         pthread_cond_wait(&alert,&alertmtx);
                         printf("Received notification from thread id: %d.\n",foo.tnum);
               }
               pthread_mutex_unlock(&alertmtx);
}
 
void *do_random(void *arg) {
int r;
time_t beg, end;
              pthread_detach(pthread_self());
              r = (int)(1 + rand() % FIRE);       
              end = beg = time(NULL);
              end += r;
              for (;;) {
                  while (end > beg) {
                        beg = time(NULL);
                        sleep(1);
                  }
                  pthread_mutex_lock(&alertmtx);
                  foo.tnum = pthread_self();
                  pthread_cond_signal(&alert);
                  end += r;
                  pthread_mutex_unlock(&alertmtx);
              }
}               

Except, instead of liveloop in main(), you'd join on the monitoring thread which would exit the process group in case of calamitous error.

I agree with jim's post. The resources used by each of the created threads can be freed even if the thread is not created as detached. After each thread finishes its task its attribute must be destroyed and pthread_join()'ed to the others to release the resources.

Both ways would work for the op. it seems to me one involves creation of a state machine and the other depends on avoiding serialization blocks imposed by pthread_join.