スレッドの数を数える方法 - 揮発性のメモ
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
Man page of GETTID
pid_t gettid(void);
と思ったら 無いらしい。
注意
Man page of GETTID
glibc はこのシステムコールに対するラッパー関数を提供していない。 syscall(2) を使って呼び出すこと。
というわけで
#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_tはstruct 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を見ることが出来た。
でもそんなの使いもんになるわけがない・・・