2012-10-21 4 views
3

현재 프로세스의 스레드 수를 얻을 수있는 syscall을 구현하려고합니다. 나는 리눅스 커널에 익숙하지 않아, 나의 이해가 제한적이다.현재 프로세스 내의 모든 스레드를 나열 하시겠습니까?

현재, 나는 모든 task_struct의 반복, 현재의 thread 그룹 리더의 PID 자신의 스레드 그룹 리더의 PID를 비교하는 것을 시도하고있다 : 그러나

// ... 
int nthreads = 0; 
struct task_struct *task_it; 
for_each_process(task_it) { 
    if (task_it->group_leader->pid == current->group_leader->pid) { 
     nthreads++; 
    } 
} 
// ... 

,이 (작동하지 않는 것 일부의 pthreads 산란 빠른 테스트는 여전히 1을주고있다. group_leader에 대한 어떤 것은 동일한 프로세스의 모든 스레드에 공통입니까?

+0

프로세스에 얼마나 많은 쓰레드가 있는지 찾기 위해'/ proc/$ pid/task /'가 작동하지 않겠는가? –

+1

http://stackoverflow.com/a/12660720/651394 –

답변

3

코드의 문제는 그 커널은 (task_structpid 필드)는 PID를 부르는 userspace가 TID (즉, sys_gettid()에 의해 반환되는 것이고 스레드 당 고유 함)를 호출하는 것입니다. 사용자 공간이 PID를 호출하는 것을 커널에서 TGID라고 부릅니다 ("태스크 그룹 ID"용) - 이것은 sys_getpid() 시스템 콜이 리턴하는 것입니다. - 당신은 실제로 그래도 TGID을 확인 할 필요가 없습니다

단지 struct task_struct * 포인터를 비교가 충분하다 :

if (task_it->group_leader == current->group_leader) { 

그런데, 당신은 단지 current가 멤버 인 thread_group 목록을 반복 할 수 (while_each_thread()), 테스트가 필요 없습니다. 또는 더 나은 것은 단지 get_nr_threads(current)을 사용하는 것입니다.

작업 목록을 반복하는 모든 메서드는 rcu_read_lock();/rcu_read_unlock();으로 묶어야합니다.

1

이 코드 덩어리가 좋은 데모입니다.

다음 C 프로그램은 노드의 프로세스 테이블에있는 모든 프로세스의 목록을 작성하고 하나의 열에 단일 프로세스의 스레드 수를 표시합니다. 이 도구를 사용하여 네트워크 문제가 발생할 때마다 네트워크 데몬이 새 스레드를 생성했음을 확인할 수있었습니다. 심각한 네트워크 문제가 로그온 문제를 담당했습니다.

#include "sys/param.h" 
#include "sys/pstat.h" 

int main (void) 
{ 

    struct pst_status * psa = NULL; 
    struct pst_status * prc = NULL;  
    struct pst_dynamic psd; 
    long    nproc = 0;  
    long    thsum = 0;  
    long    i;     

    if (pstat_getdynamic(&psd, sizeof(psd), 1, 0) == -1) 
    (void)perror("pstat_getdynamic failed"); 

    // Get the number of active processes from pst_dynamic 
    nproc = psd.psd_activeprocs; 
    psa = (struct pst_status *)malloc(nproc * sizeof(struct pst_status)); 

    // Read the info about the active processes into the array 'psa' 
    if (pstat_getproc(psa, sizeof(struct pst_status), nproc, 0) == -1) 
    (void)perror("pstat_getproc failed"); 

    (void)printf("\n\n------------------------------------------------------------------------------"); 
    (void)printf("\n %5s | %5s |%7s| %5s | %s", "PID", "UID", "Threads", "RSS", "Command"); 
    (void)printf("\n------------------------------------------------------------------------------"); 

    // Report the process info as required 
    prc = (struct pst_status *)psa;  
    for (i=0; i < nproc; i++) 
    { 
    (void)printf("\n %5ld | ", prc->pst_pid); 
    (void)printf("%5ld | ", prc->pst_uid); 
    (void)printf("%5ld | ", prc->pst_nlwps); 
    (void)printf("%5ld | ", prc->pst_rssize); 
    (void)printf("%s ", prc->pst_cmd); 
    thsum += prc->pst_nlwps; 
    ++prc;   
    } 

    (void)printf("\n\n*** %ld processes, %ld threads running\n\n", nproc, thsum); 
    (void)free(psa);  
    (void)exit(0); 
} 

여기 찾았 http://h21007.www2.hp.com/portal/site/dspp/menuitem.863c3e4cbcdc3f3515b49c108973a801?ciid=060818f70fe0211018f70fe02110275d6e10RCRD

여기에 사용 된 task_struct 다른 링크를 다음과 같습니다 http://tuxthink.blogspot.com/2011/03/using-foreachprocess-in-proc-entry.html

+0

'pstat_getproc' 함수를 사용하는 대신 task_struct (s)를 통해이 작업을 수행 할 수 있습니까? – Darthfett

+0

Ok, task_struct를 사용하는 다른 링크를 찾았습니다. 당신이 필요로하는 것을하는 것처럼 보입니다. 위의 솔루션에 링크를 추가했습니다. 행운을 빕니다 :) – DaveyLaser

관련 문제