【问题标题】:List all threads within the current process?列出当前进程中的所有线程?
【发布时间】:2026-01-10 03:35:01
【问题描述】:

我正在尝试实现一个系统调用,它允许我获取当前进程的线程数。我是 Linux 内核的新手,所以对它的理解有限。

目前,我正在尝试遍历所有task_structs,并将其线程组组长的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++;
    }
}
// ...

但是,这似乎不起作用(产生一些 pthread 的快速测试仍然给出 1group_leader 对同一进程中的所有线程是通用的吗?

【问题讨论】:

标签: multithreading linux-kernel


【解决方案1】:

您的代码的问题在于内核调用的 PID(task_structpid 字段)是用户空间调用的 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(); 中才能正确。

【讨论】:

    【解决方案2】:

    这段代码是一个很好的演示。

    以下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

    【讨论】:

    • 是否可以通过 task_struct(s) 来代替pstat_getproc 函数?
    • 好的,找到另一个使用 task_struct 的链接。看起来做你需要它做的事情。我在上面的解决方案中添加了链接。祝你好运:)
    最近更新 更多