title: zombie threads on AIX 6.1
body: <p>I am having issues on AIX 6.1 where once a thread is created it appears not to die. </p>
  
  <p>Compile with: 
     gcc -pthread sample.c 
     cc_r sample.c </p>
  
  <p>Both have same result. </p>
  
  <p>I have attempted to detach the thread in three ways.<br>
     1) Main method calls pthread_detach after its created. 
     2) Main method attempts to create thread detached through attr arg. 
     3) Thread function calling pthread_detach. </p>
  
  <p>My attempts to track thread start/stop result in all threads finishing. </p>
  
  <p>ALl three as per this call have numerous threads in state Z </p>
  
  <pre><code>-bash-4.2# ps -mo THREAD -p `ps -ef | grep a.out | awk '{print $2}'` 
      USER    PID   PPID      TID ST  CP PRI SC    WCHAN        F     TT BND COMMAND 
      root 340028 278750        - A    0  60 11 f100010019c574b0   200001  pts/0   - ./a.out 10 3 
         -      -      -   450679 Z    0  60  1        -   c00001      -   - - 
         -      -      -   561215 Z    0  60  1        -   c00001      -   - - 
         -      -      -   573523 Z    0  60  1        -   c00001      -   - - 
         -      -      -   663653 Z    0  60  1        -   c00001      -   - - 
         -      -      -   684203 Z    0  60  1        -   c00001      -   - - 
         -      -      -   745711 Z    0  60  1        -   c00001      -   - - 
         -      -      -   753695 Z    0  60  1        -   c00001      -   - - 
         -      -      -   987139 Z    0  60  1        -   c00001      -   - - 
         -      -      -  1007867 Z    0  60  1        -   c00001      -   - - 
         -      -      -  1523761 S    0  60  1 f100010019c574b0   410400      -   - - 
         -      -      -  1536067 Z    0  60  1        -   c00001      -   - - 
  </code></pre>
  
  <p>Here is the code (I know its sloppy!  Please excuse!) </p>
  
  <pre><code>#include &lt;stdlib.h&gt; 
  #include &lt;stdio.h&gt; 
  #include &lt;string.h&gt; 
  #include &lt;ctype.h&gt; 
  #include &lt;unistd.h&gt; 
  #include &lt;pthread.h&gt; 
  #include &lt;limits.h&gt; 
  
  #define DETACH_NONE                                                0 
  #define DETACH_METHOD_DETACH_IN_MAIN         1 
  #define DETACH_AT_PTHREAD_CREATE                2 
  #define DETACH_IN_THREAD_FUNC                        3 
  int g_nDetachMethod = DETACH_METHOD_DETACH_IN_MAIN; 
  
  void increment_count(); 
  void decrement_count(); 
  long long get_count(); 
  void set_count( long long c ); 
  void *PrintHello2( void* ptr ); 
  void displayThreadStatus( pthread_t tid ); 
  void displayTopOutput(); 
  
  void *PrintHello2( void* ptr ) 
  { 
          int rc; 
          pthread_t tid = pthread_self(); 
          sched_yield(); 
          increment_count(); 
                  sleep( rand() % 10 + 1 ); 
                  displayThreadStatus( tid ); 
                  if( g_nDetachMethod == DETACH_IN_THREAD_FUNC ) 
                  { 
                          rc = pthread_detach( tid ); 
                          printf("\t\tDetach result: %d.\n", rc); 
                          displayThreadStatus( tid ); 
                  } 
          decrement_count(); 
          pthread_exit (NULL); 
  } 
  
  int main( int argc, char *argv[] ) 
  { 
          pthread_t thds; 
          int i, count, num_threads, rc; 
  
          set_count( 0 ); 
  
          if( argc &lt; 2 ) 
          { 
                  printf("Specify on the command line which detach method to use and the number of threads.\n"); 
                  printf("Usage: %s threads detachmethod\n", argv[0]); 
                  printf("\t     threads: The count of child threads to spawn.  Default=10\n"); 
                  printf("\tdetachmethod: The point at which detach should be called.  Default=%d\n", DETACH_METHOD_DETACH_IN_MAIN); 
                  printf("\t\t\t%d: Do not attempt to detach.  Default behaviour is joinable.\n"); 
                  printf("\t\t\t%d: Call pthread_detach right after pthread_create in main.\n", DETACH_METHOD_DETACH_IN_MAIN); 
                  printf("\t\t\t%d: Call pthread_create with pthread_attr_setdetachstate attribute set to PTHREAD_CREATE_DETACHED.\n", DETACH_AT_PTHREAD_CREATE); 
                  printf("\t\t\t%d: Call pthread_detach inside the thread function.\n", DETACH_IN_THREAD_FUNC); 
                  printf("\nExample:\n"); 
                  printf("\t a.out 10 %d\n", DETACH_METHOD_DETACH_IN_MAIN); 
                  exit(0); 
          } 
  
          printf("Using Threads:\"%s\" Detach method:\"%s\"\n", argv[1], argv[2]); 
  
          num_threads = atoi( argv[1] ); 
          g_nDetachMethod = atoi( argv[2] ); 
  
          printf("\n\n=======  CREATING %d THREADS =======\n", num_threads); 
          for( i = 0; i &lt; num_threads; i++ ) 
          { 
                  printf( "\n\tcreating thread : %d \n", i ); 
                  if( g_nDetachMethod == DETACH_AT_PTHREAD_CREATE ) 
                  { 
                          pthread_attr_t tattr; 
                          pthread_attr_init(&amp;tattr); 
                          pthread_attr_setdetachstate(&amp;tattr,PTHREAD_CREATE_DETACHED); 
                          pthread_create( &amp;thds, &amp;tattr, PrintHello2, (void*) NULL ); 
                  } 
                  else 
                  { 
                          pthread_create( &amp;thds, NULL, PrintHello2, (void*) NULL ); 
                          if( g_nDetachMethod == DETACH_METHOD_DETACH_IN_MAIN ) 
                          { 
                                  rc = pthread_detach( thds ); 
                                  printf("\t\tDetach result: %d.\n", rc); 
                          } 
                  } 
          } 
  
          printf("\n\n=======  WAITING FOR THREADS TO FINISH =======\n"); 
          for( i = 0; i &lt; 20; i++ ) 
          { 
                  sleep( 1 ); 
                  count = get_count(); 
                  printf( "\tLoop: %d, Active Threads: %d, Sleep seconds: %d\n", i, count, (i + 1) ); 
                  if( count == 0 ) 
                          break; 
          } 
  
          displayTopOutput(); 
          printf("\n\n=======  WAITING FOR 10 SECONDS TO MANUALLY QUERY FOR DEFUNCT PROCESSES =======\n"); 
          printf("ps -mo THREAD -p `ps -ef | grep a.out | awk '{print $2}'`\n"); 
          for( i = 10; i &gt;= 0; i-- ) 
          { 
                  sleep( 1 ); 
                  printf( "\r%d seconds remaining.", i ); 
                  fflush (stdout); 
          } 
  
          count = get_count(); 
          printf("\n\n=======  FINAL STATUS Active Threads: %d =======\n", count ); 
          displayTopOutput(); 
          return 0; 
  } 
  
  void displayThreadStatus( pthread_t tid ) 
  { 
  /*        int state; 
          pthread_attr_t attr; 
  
          pthread_getattr_np( pthread_self(), &amp;attr); 
          pthread_attr_getdetachstate( &amp;attr, &amp;state ); 
          printf("\t\t[%d]: %s\n", tid, state == PTHREAD_CREATE_DETACHED? "PTHREAD_CREATE_DETACHED": "PTHREAD_CREATE_JOINABLE"); 
          */ 
  } 
  
  void displayTopOutput() 
  { 
          if( fork() != 0 ) 
          { 
                  int status; 
                  wait( &amp;status ); 
                  return; 
          } 
          pid_t pid = getppid(); 
          char buffer[10]; 
          sprintf( buffer, "%d", (int) pid ); 
          printf( "PID: %s\n", buffer ); 
          /* execl( "/usr/bin/top", "top", "-H", "-b", "-n", "1", "-d", "1", "-p", buffer, (char *) NULL ); */ 
          execl("/usr/bin/ps", "ps", "-mo", "THREAD", "-p", buffer, (char *) NULL ); 
          printf("\n"); 
          exit( 0 ); 
  } 
  
  pthread_mutex_t count_mutex; 
  long long count=0; 
  
  void increment_count() 
  { 
          pthread_mutex_lock( &amp;count_mutex ); 
          count = count + 1; 
          pthread_mutex_unlock( &amp;count_mutex ); 
  } 
  
  void decrement_count() 
  { 
          pthread_mutex_lock( &amp;count_mutex ); 
          count = count - 1; 
          pthread_mutex_unlock( &amp;count_mutex ); 
  } 
  
  long long get_count() 
  { 
          long long c; 
          pthread_mutex_lock( &amp;count_mutex ); 
          c = count; 
          pthread_mutex_unlock( &amp;count_mutex ); 
          return (c); 
  } 
  
  void set_count( long long c ) 
  { 
          pthread_mutex_lock( &amp;count_mutex ); 
          count = c; 
          pthread_mutex_unlock( &amp;count_mutex ); 
  } 
  </code></pre>