揮発性のメモ2

知識をメモ書きしておく

スレッドIDを取得する

スレッドの数を数える方法 - 揮発性のメモ
LWP番号を見たい。

$ ps -Lm 26443
  PID   LWP TTY      STAT   TIME COMMAND
26443     - pts/5    -      0:00 ./a.out
    - 26443 -        Sl+    0:00 -
    - 26444 -        Sl+    0:00 -
    - 26445 -        Sl+    0:00 -
    - 26446 -        Sl+    0:00 -

このLWP番号をプログラムで取得したい。


gettid()という関数があるらしい。

#include
pid_t gettid(void);

Man page of GETTID

と思ったら 無いらしい。

注意
glibc はこのシステムコールに対するラッパー関数を提供していない。 syscall(2) を使って呼び出すこと。

Man page of GETTID

Man page of SYSCALL


というわけで

#include <unistd.h>
#include <sys/syscall.h>
#include <sys/types.h>

pid_t gettid(void)
{
    return syscall(SYS_gettid);
}

これでおk


テスト用のソース

#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/syscall.h>
#include <sys/types.h>

pid_t gettid(void)
{
    return syscall(SYS_gettid);
}

void *gettidtest( void *arg )
{
    int number = (int)arg;

    printf("thread %d:tid=%d\n", number, gettid());
    printf("thread %d:pid=%d\n", number, getpid());
    printf("thread %d:ppid=%d\n", number, getppid());

    sleep(100);
    return NULL;
}

int main( int argc, char **argv )
{
    int i;
    pthread_t p;

    for(i=1;i<=3;i++){
        pthread_create( &p, NULL, gettidtest, (void*)i );
    }
    gettidtest( 0 );

    return 0;
}

実行結果

$ gcc -g -Wall -lrt gettidtest.c
$ ./a.out
thread 1:tid=26476
thread 2:tid=26477
thread 3:tid=26478
thread 2:pid=26475
thread 2:ppid=24458
thread 3:pid=26475
thread 3:ppid=24458
thread 0:tid=26475
thread 0:pid=26475
thread 0:ppid=24458
thread 1:pid=26475
thread 1:ppid=24458

思ってたより起動順序がバラつくもんだ

pthread_tから取得する方法?

上の方法だと親は直接子のスレッドIDを取得できない。
出来れば、pthread_tとかそのあたりから取得したい。
・・・
gadgethack: linuxのLWP番号とpthread_tの関係
http://ms.megadriver.yi.org/~fumi/2010/11/pthread_t-%E3%81%AE%E3%83%9D%E3%82%A4%E3%83%B3%E3%82%BF%E3%81%8C%E7%A4%BA%E3%81%99%E3%82%82%E3%81%AE%EF%BC%88pthread_create-%E7%AC%AC%E4%B8%80%E5%BC%95%E6%95%B0%EF%BC%8Fpthread_self%E6%88%BB%E3%82%8A/
・・・
なんかすごく面倒くさい話になってきた。


とりあえず、pthread_tstruct pthreadのアドレスを格納しているものらしい。
glibc-2.7/nptl/descr.hを見てみると

/* Thread descriptor data structure.  */
struct pthread
{
  union
  {
#if !TLS_DTV_AT_TP
    /* This overlaps the TCB as used for TLS without threads (see tls.h).  */
    tcbhead_t header;
#else
    struct
    {
      int multiple_threads;
      int gscope_flag;
# ifndef __ASSUME_PRIVATE_FUTEX
      int private_futex;
# endif
    } header;
#endif

    /* This extra padding has no special purpose, and this structure layout
       is private and subject to change without affecting the official ABI.
       We just have it here in case it might be convenient for some
       implementation-specific instrumentation hack or suchlike.  */
    void *__padding[16];
  };

  /* This descriptor's link on the `stack_used' or `__stack_user' list.  */
  list_t list;

  /* Thread ID - which is also a 'is this thread descriptor (and
     therefore stack) used' flag.  */
  pid_t tid;

  /* Process ID - thread group ID in kernel speak.  */
  pid_t pid;
以下続く

というわけで、list_tは2ワード分なので計18ワード後ろをダンプしたら確かにスレッドIDを見ることが出来た。


でもそんなの使いもんになるわけがない・・・