2014-10-07 128 views
0

我在AIX 6.1上遇到问题,一旦创建线程,它看起来不会死。AIX 6.1上的僵尸线程

编译: GCC -pthread sample.c文件 cc_r sample.c文件

两者有相同的结果。

我试图用三种方法分离线程。
1)主方法创建后调用pthread_detach。 2)Main方法尝试创建通过attr arg分离的线程。 3)线程函数调用pthread_detach。

我试图跟踪线程开始/停止导致所有线程完成。

所有三个按照这一呼吁在状态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  - - - 

下面是代码(我知道它的马虎!请原谅!)

#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); 
} 

回答

0

我引用描述并行线程的文章实现对AIX:


内核维护一个列表,称为deathrow,LWP和柯rnel线程已退出,以便在需要创建新的(fork())时收获终止的LWP/kthread。如果一个LWP/kthread在僵尸列表中可用,内核不需要为新的k线程分配数据结构和堆栈;它仅使用僵尸kthread中的结构和堆栈,并将kthread链接到发出fork(2)(或thread_create())命令的进程。

在进程创建流程中,当forklwp()代码调用lwp_create()时,lwp_create()首先在deathrow上查找僵尸线程。如果存在,则LWP,kthread和堆栈会与进程关联,并且内核不必在fork()过程中分配新k线程,LWP和堆栈空间。内核简单地从死亡列表中获取结构,适当地链接指针,然后继续前进。从lwp_create()调用的thread_create()(内核线程创建,而不是用户线程API)传递LWP数据和堆栈,从而避免执行任何内核内存分配。


全部文章是在这里: http://flylib.com/books/en/2.830.1.30/1/