3

現在のプロセスのスレッド数を取得できるシステムコールを実装しようとしています。私は Linux カーネルに慣れていないため、理解が限られています。

現在、すべての s を反復処理し、task_structそれらのスレッド グループ リーダーの 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 を生成する簡単なテストでは、まだ1.group_leaderは同じプロセス内のすべてのスレッドに共通ですか?

4

2 に答える 2

4

あなたのコードの問題は、カーネルが PID (のpidフィールドtask_struct) と呼ぶものは、ユーザー空間が TID と呼ぶものです (つまり、それはによって返されsys_gettid()、スレッドごとに一意です)。ユーザー空間が PID と呼ぶものは、カーネルでは TGID (「タスク グループ ID」) と呼ばれます。これが、sys_getpid()syscall が返すものです。

ただし、実際に TGID を確認する必要はありません。struct task_struct *ポインターを比較するだけで十分です。

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

ちなみに、(with ) のメンバーであるthread_groupリストを反復処理するだけで、テストはまったく必要ありません。またはさらに良いことに、単に使用します。currentwhile_each_thread()get_nr_threads(current)

タスク リストをループするすべてのメソッドは、正しいようにrcu_read_lock();/でラップする必要があることに注意してください。rcu_read_unlock();

于 2012-10-23T06:34:54.350 に答える
1

このコードのチャンクは、良いデモンストレーションです。

次の C プログラムは、ノードのプロセス テーブルにすべてのプロセスのリストを作成し、単一のプロセスのスレッド数を 1 つの列に表示します。このツールを使用すると、ネットワークの問題が発生するたびに、ネットワーク デーモンが新しいスレッドを作成したことを特定できました。深刻なネットワークの問題がログオンの問題の原因でした。

#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

于 2012-10-21T21:42:22.293 に答える