Linux C/C++ では、スレッド レベルの操作は通常、pthread ライブラリを通じて実行されます。 pthread ライブラリには次の関数があります: pthread_t pthread_self(void); これは、pthread_self 関数を呼び出したスレッドの「ID」を参照する pthread_t 型の変数を返します。 この「ID」をどのように理解しますか? この「ID」は、各スレッドの pthread ライブラリによって定義されるプロセス内の一意の識別子であり、pthread ライブラリによって管理されます。 各プロセスには独自の独立したメモリ空間があるため、この「ID」の範囲はシステム レベルではなくプロセス レベルになります (カーネルはこれを認識しません)。 実際、pthread ライブラリはカーネルが提供するシステム コール (clone など) を通じてスレッドを作成し、カーネルはスレッドを一意に識別するために各スレッドに対してシステム全体で一意の「ID」を作成します。 このシステムのグローバルに一意の「ID」は、スレッド PID (プロセス ID)、または TID (スレッド ID) と呼ばれ、LWP (軽量プロセス = スレッド) とも呼ばれます。 カーネル内のスレッドのシステム全体で一意の「ID」を表示するにはどうすればよいでしょうか?大きく分けて以下の方法があります。 テストコード: メイン.c #define _GNU_SOURCE #include <stdio.h> #include <stdlib.h> #include <文字列.h> #include <unistd.h> #include <pthread.h> void *start_routine(void *arg) { char msg[32] = ""; snprintf(msg, sizeof(msg)-1, "thd%d: i am thd%d\n", *((int *)arg), *((int *)arg)); 一方(1){ 書き込み(1, メッセージ, strlen(メッセージ)); 睡眠(1); } } int main() { 整数 th1 = 1; tid1 はスレッドのインスタンスを生成する。 pthread_create(&tid1, NULL, start_routine, &th1); 整数 th2 = 2; pthread_tid2 の引数は tid2 です。 pthread_create(&tid2, NULL, start_routine, &th2); 整数 th3 = 3; pthread_tid3 の引数は、 tid3 です。 pthread_create(&tid3, NULL, start_routine, &th3); const char *msg = "main: 私はメインです\n"; 一方(1){ 書き込み(1, メッセージ, strlen(メッセージ)); 睡眠(1); } 0を返します。 } メインスレッドでは、pthread ライブラリを通じて 3 つのスレッドが作成され、「i am xxx」という情報が継続的に出力されます。 実行出力:
方法 1: ps -Lf $pid [test1280@localhost ~]$ ps -Lf 11029 UID PID PPID LWP C NLWP STIME TTY STAT TIME CMD test1280 11029 9374 11029 0 4 10:58 pts/0 Sl+ 0:00 ./main test1280 11029 9374 11030 0 4 10:58 pts/0 Sl+ 0:00 ./main test1280 11029 9374 11031 0 4 10:58 pts/0 Sl+ 0:00 ./main test1280 11029 9374 11032 0 4 10:58 pts/0 Sl+ 0:00 ./main 11209 は監視対象のプロセスの PID です。 出力は、このプロセスに 4 つのスレッドが含まれており、それらの PID がすべて 11209、それらの PPID がすべて 9374 であることを示しています。LWP は、探しているスレッド ID です。 LWP がプロセスの PID と一致するスレッドがあり、そのスレッドがメイン スレッドであることに気付きました。 -L スレッドを表示します。LWP と NLWP の列も表示できます。 -f は完全形式のリストを表示します。 方法 2: pstree -p $pid [test1280@localhost ~]$ pstree -p 11029 メイン(11029)─┬─{メイン}(11030) ├─{メイン}(11031) └─{メイン}(11032) 方法3: top -Hp $pid [test1280@localhost ~]$ トップ -Hp 11029 プロセス PID は top で指定されます。出力には 4 つのスレッドが含まれます。PID フィールドを使用して、各スレッドの PID (TID/LWP) を取得できます。 男のトップ -H:スレッド切り替え 最後に記憶された「H」状態を反転した状態で上から開始します。 このトグルをオンにすると、すべての個別のスレッドが表示されます。 それ以外の場合、top はプロセス内のすべてのスレッドの合計を表示します。 -p: PIDを監視する 方法4: ls -l /proc/$pid/task/ [test1280@localhost ~]$ ls -l /proc/11029/task/ 合計 0 dr-xr-xr-x. 6 test1280 test1280 0 2月27日 10:58 11029 dr-xr-xr-x. 6 test1280 test1280 0 2月27日 10:58 11030 dr-xr-xr-x. 6 test1280 test1280 0 2月27日 10:58 11031 dr-xr-xr-x. 6 test1280 test1280 0 2月27日 10:58 11032 方法5: pidstat -t -p $pid [test1280@localhost ~]$ pidstat -t -p 11029 Linux 2.6.32-642.el6.x86_64 (localhost.localdomain) 2019 年 2 月 27 日 _x86_64_ (4 CPU) 11:20:39 AM TGID TID %usr %system %guest %CPU CPU コマンド 11:20:39 AM 11029 - 0.00 0.00 0.00 0.00 1 メイン 午前11:20:39 - 11029 0.00 0.00 0.00 0.00 1 |__メイン 午前11:20:39 - 11030 0.00 0.00 0.00 0.00 1 |__メイン 午前11:20:39 - 11031 0.00 0.00 0.00 0.00 0 |__メイン 午前11:20:39 - 11032 0.00 0.00 0.00 0.00 3 |__メイン TGID はスレッド グループ ID です。メイン スレッドの TID は、メイン スレッドのスレッド グループ ID と同じであり、メイン スレッドが配置されているプロセスのプロセス ID と同じです。 男のピッドスタット -t 選択したタスクに関連付けられているスレッドの統計も表示します。 このオプションはレポートに次の値を追加します。 TGID:スレッド グループ リーダーの識別番号。 TID: 監視対象のスレッドの識別番号。 方法6: ソースコードの取得 メイン.c #define _GNU_SOURCE #include <stdio.h> #include <stdlib.h> #include <文字列.h> #include <unistd.h> #include <pthread.h> #include <sys/types.h> #include <sys/syscall.h> pid_t gettid() { syscall(SYS_gettid) を返します。 } void *start_routine(void *arg) { pid_t pid = gettid(); pthread_t tid = pthread_self(); printf("thd%d: pid=%d, tid=%lu\n", *((int *)arg), pid, tid); char msg[32] = ""; snprintf(msg, sizeof(msg)-1, "thd%d: i am thd%d\n", *((int *)arg), *((int *)arg)); 一方(1){ 書き込み(1, メッセージ, strlen(メッセージ)); 睡眠(1); } } int main() { pid_t pid = gettid(); pthread_t tid = pthread_self(); printf("メイン: pid=%d, tid=%lu\n", pid, tid); 整数 th1 = 1; pthread_t tid1; pthread_create(&tid1, NULL, start_routine, &th1); 整数 th2 = 2; pthread_tid2 の引数は tid2 です。 pthread_create(&tid2, NULL, start_routine, &th2); 整数 th3 = 3; pthread_tid3 の引数は、 tid3 です。 pthread_create(&tid3, NULL, start_routine, &th3); const char *msg = "main: 私はメインです\n"; 一方(1){ 書き込み(1, メッセージ, strlen(メッセージ)); 睡眠(1); } 0を返します。 } syscall(SYS_gettid) システムコールは、カーネル内のスレッドの ID である pid_t 型の値を返します。 [test1280@localhost 20190227]$ gcc -o main main.c -lpthread [test1280@localhost 20190227]$ ./main メイン: pid=11278、tid=140429854775040 メイン:私はメインです thd3: pid=11281、tid=140429833787136 thd3: 私はthd3です thd2: pid=11280、tid=140429844276992 thd2: 私はthd2です thd1: pid=11279、tid=140429854766848 thd1: 私はthd1です … スレッドの PID (TID、LWP) の値は何ですか? 多くのコマンド パラメータの PID は、実際には、taskset、strace、その他のコマンドなどのカーネル内のスレッドの ID を参照します。 たとえば、taskset コマンドは、プロセスを指定された CPU コアにバインドできます。 プロセスがマルチスレッド モードの場合、taskset を直接使用するとメイン スレッドのみがバインドされ、他のスレッドはバインドされず、有効になりません。 例: # 11282 プロセスを CPU コア 0 にバインドします [test1280@localhost ~]$ ps -Lf 11282 UID PID PPID LWP C NLWP STIME TTY STAT TIME CMD test1280 11282 9374 11282 0 4 11:33 pts/0 Sl+ 0:00 ./main test1280 11282 9374 11283 0 4 11:33 pts/0 Sl+ 0:00 ./main test1280 11282 9374 11284 0 4 11:33 pts/0 Sl+ 0:00 ./main test1280 11282 9374 11285 0 4 11:33 pts/0 Sl+ 0:00 ./main [test1280@localhost ~]$ タスクセット -pc 0 11282 pid 11282 の現在のアフィニティ リスト: 0-3 pid 11282 の新しいアフィニティ リスト: 0 # 他のスレッドが本当にCPUコア0にバインドされているかどうかを確認します [test1280@localhost ~]$ taskset -pc 11283 pid 11283 の現在のアフィニティ リスト: 0-3 [test1280@localhost ~]$ タスクセット -pc 11284 pid 11284 の現在のアフィニティ リスト: 0-3 [test1280@localhost ~]$ タスクセット -pc 11285 pid 11285 の現在のアフィニティ リスト: 0-3 [test1280@localhost ~]$ タスクセット -pc 11282 pid 11282 の現在のアフィニティ リスト: 0 # この時点では、メインスレッドのみが実際に CPU コア 0 にバインドされています。 # 他の 4 つのスレッドを CPU コア 0 にバインドします [test1280@localhost ~]$ taskset -pc 0 11283 pid 11283 の現在のアフィニティ リスト: 0-3 pid 11283 の新しいアフィニティ リスト: 0 [test1280@localhost ~]$ タスクセット -pc 0 11284 pid 11284 の現在のアフィニティ リスト: 0-3 pid 11284 の新しいアフィニティ リスト: 0 [test1280@localhost ~]$ タスクセット -pc 0 11285 pid 11285 の現在のアフィニティ リスト: 0-3 pid 11285 の新しいアフィニティ リスト: 0 # この時点で、プロセス PID=11282 のプロセスのすべてのスレッドは CPU コア 0 でのみ実行されます。 同様に、strace はスレッド PID を指定し、スレッドによって実行されたシステム コールとシグナルを追跡できます。 Linux スレッドの PID (TID、LWP) を取得するいくつかの方法についての記事はこれで終わりです。Linux スレッドの PID を取得する方法の詳細については、123WORDPRESS.COM の以前の記事を検索するか、次の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。 以下もご興味があるかもしれません:
|
<<: JS は VUE コンポーネントに基づいて都市リスト効果を実装します
>>: Vueはカスタムツリーコンポーネントを再帰的に実装します
基本概念操作の前に、まずいくつかの基本的な概念を理解する必要がありますディスクLinux システムで...
操作要素の詳細については、前回の記事を参照してください。JavaScript WebAPI、DOM、...
この細線の表を作成する方法については、Baidu で検索すると、表に対して border="...
CSS は、スクロールを許可しながらスクロール バーを非表示にするために Overflow を設定し...
MySQL 8.0.12のインストールと設定方法を記録してみんなで共有します。 1. インストール1...
mysqlインストーラコミュニティ8.0.16.0インストールグラフィックチュートリアル、参考までに...
日常の開発タスクでは、データ テーブル内のグループ化フィールドに基づいて統計データを取得するために、...
Nginx の書き換え機能は、リダイレクトと同様に、URL アドレスを一時的または永続的に新しい場所...
この記事では、jQueryでカルーセルチャートを実装するための具体的なコードを参考までに共有します。...
1. 何ですか視差スクロールとは、複数の背景レイヤーを異なる速度で動かすことで、3次元のモーション...
書き換えモジュールは ngx_http_rewrite_module モジュールです。その主な機能は...
目次1. テンプレート2. ジェネリック3. ジェネリック再帰4. デフォルトのジェネリックパラメー...
目次父から息子へ: 1. 親コンポーネントのサブコンポーネントタグに、サブコンポーネントに渡されるデ...
Oracle データベースから MySQL データベースへの移行では、Oracle データベース モ...
以前、プロジェクトでQRコードをスキャンして情報を表示する機能を開発する必要がありました。インターネ...