Zombie threads on AIX...
 
I am having issues on AIX 6.1 where once a thread is created it appears not to die. 
Compile with: 
   gcc -pthread sample.c 
   cc_r sample.c 
Both have same result. 
I have attempted to detach the thread in three ways.   
   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. 
My attempts to track thread start/stop result in all threads finishing. 
ALl three as per this call have numerous threads in state Z 
-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      -   - - 
Here is the code (I know its sloppy!  Please excuse!) 
#include <stdlib.h> 
#include <stdio.h> 
#include <string.h> 
#include <ctype.h> 
#include <unistd.h> 
#include <pthread.h> 
#include <limits.h> 
#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 < 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 < num_threads; i++ ) 
        { 
                printf( "\n\tcreating thread : %d \n", i ); 
                if( g_nDetachMethod == DETACH_AT_PTHREAD_CREATE ) 
                { 
                        pthread_attr_t tattr; 
                        pthread_attr_init(&tattr); 
                        pthread_attr_setdetachstate(&tattr,PTHREAD_CREATE_DETACHED); 
                        pthread_create( &thds, &tattr, PrintHello2, (void*) NULL ); 
                } 
                else 
                { 
                        pthread_create( &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 < 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 >= 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(), &attr); 
        pthread_attr_getdetachstate( &attr, &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( &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( &count_mutex ); 
        count = count + 1; 
        pthread_mutex_unlock( &count_mutex ); 
} 
void decrement_count() 
{ 
        pthread_mutex_lock( &count_mutex ); 
        count = count - 1; 
        pthread_mutex_unlock( &count_mutex ); 
} 
long long get_count() 
{ 
        long long c; 
        pthread_mutex_lock( &count_mutex ); 
        c = count; 
        pthread_mutex_unlock( &count_mutex ); 
        return (c); 
} 
void set_count( long long c ) 
{ 
        pthread_mutex_lock( &count_mutex ); 
        count = c; 
        pthread_mutex_unlock( &count_mutex ); 
}