Linux cプログラムで、pthreadライブラリによって作成されたスレッドのスレッドIDを出力する方法は?
例:プロセスのpidを取得するにはgetpid()
回答:
pthread_self()
関数は現在のスレッドのスレッドIDを与えます。
pthread_t pthread_self(void);
このpthread_self()
関数は、呼び出し元のスレッドのPthreadハンドルを返します。pthread_self()関数は、呼び出し元のスレッドの整数スレッドを返しません。を使用pthread_getthreadid_np()
して、スレッドの整数識別子を返す必要があります。
注意:
pthread_id_np_t tid;
tid = pthread_getthreadid_np();
これらの呼び出しよりも大幅に高速ですが、同じ動作を提供します。
pthread_id_np_t tid;
pthread_t self;
self = pthread_self();
pthread_getunique_np(&self, &tid);
pthread_threadid_np
。プロジェクトに使用する必要があるため、iOSおよびOSXプラットフォームでそのAPIの信頼性を確認する必要があります。opensource.apple.com/source/Libc/Libc-583/pthreads/pthread.hのリンクを参照しましたが、それらが正しいかどうかはわかりません。
_np
するために、ポータブルではないことを意味します。Linuxには独自の_np
ものがありますが、Appleのものは含まれていませんpthread_getthreadid_np
。
何?その人はLinux固有で、getpid()に相当するものを求めました。BSDやAppleではありません。答えはgettid()であり、整数型を返します。次のように、syscall()を使用して呼び出す必要があります。
#include <sys/types.h>
#include <unistd.h>
#include <sys/syscall.h>
....
pid_t x = syscall(__NR_gettid);
これはLinux以外のシステムに移植できない場合がありますが、threadidは直接比較可能であり、取得が非常に高速です。通常の整数のように(LOGなどで)印刷できます。
getpid()
例として挙げました。セマンティクスが難しい仕様であるとは言いませんでした。Linux以外の他のコミュニティ(FreeBSD、Illumos、OS Xなど)がそれらの恩恵を受けることができるように、POSIX互換の方法で物事を行うことを人々に認識させることは、「誇示」ではありません。私が言ったように、Linuxは本当に次のWindowsになっていると思います。
他の回答に記載されているように、pthreadsは、統合スレッドIDを取得するためのプラットフォームに依存しない方法を定義していません。
Linuxシステムでは、次のようにしてスレッドIDを取得できます。
#include <sys/types.h>
pid_t tid = gettid();
多くのBSDベースのプラットフォームでは、この回答https://stackoverflow.com/a/21206357/316487は移植性のない方法を提供します。
ただし、スレッドIDが必要だと思う理由が、制御している別のスレッドと同じスレッドで実行しているか、別のスレッドで実行しているかを知るためである場合は、このアプローチに何らかのユーティリティが見つかる可能性があります。
static pthread_t threadA;
// On thread A...
threadA = pthread_self();
// On thread B...
pthread_t threadB = pthread_self();
if (pthread_equal(threadA, threadB)) printf("Thread B is same as thread A.\n");
else printf("Thread B is NOT same as thread A.\n");
メインスレッドを使用しているかどうかを知る必要がある場合は、この質問への回答に記載されている追加の方法があります。pthread_selfがプロセスのメイン(最初の)スレッドであるかどうかを確認するにはどうすればよいですか?。
pthread_getthreadid_np
私のMacOSXにはありませんでした。 pthread_t
不透明(OPAQUE)型です。頭を殴らないでください。に割り当てて、void*
それを良いと呼ぶだけです。をprintf
使用する必要がある場合%p
。
質問が明確でないだけでなく、ほとんどの人もその違いを認識していないと思います。次のことわざを調べてください。
POSIXスレッドIDは、Linux固有の
gettid()
システムコールによって返されるスレッドIDと同じではありません。POSIXスレッドIDは、スレッドの実装によって割り当てられ、維持されます。によって返されるスレッドIDはgettid()
、カーネルによって割り当てられた番号(プロセスIDと同様)です。Linux NPTLスレッドの実装では各POSIXスレッドに一意のカーネルスレッドIDがありますが、アプリケーションは通常、カーネルIDについて知る必要はありません(また、カーネルIDを知っていることに依存している場合は移植できません)。抜粋:Linuxプログラミングインターフェイス:LinuxおよびUNIXシステムプログラミングハンドブック、Michael Kerrisk
私見ですが、1,2,3...
スレッドごとなど、昇順で数値を保持する変数を定義する構造を渡すポータブルな方法は1つだけです。これを行うことにより、スレッドのIDを追跡できます。それでも、int pthread_equal(tid1, tid2)
関数を使用する必要があります。
if (pthread_equal(tid1, tid2)) printf("Thread 2 is same as thread 1.\n");
else printf("Thread 2 is NOT same as thread 1.\n");
gettid()
は実際には良い提案です、ありがとう!しかし、私はここでセルゲイL.によって答えを追跡するために必要な:stackoverflow.com/a/21280941/2430526
スレッドIDを取得する別の方法もあります。でスレッドを作成している間
int pthread_create(pthread_t * thread, const pthread_attr_t * attr, void * (*start_routine)(void *), void *arg);
関数呼び出し; 最初のパラメーターpthread_t * thread
は実際にはスレッドID(つまり、bits / pthreadtypes.hで定義されているunsigned long int)です。また、最後の引数void *arg
は、void * (*start_routine)
スレッド化される関数に渡される引数です 。
複数の引数を渡し、構造体へのポインターを送信する構造体を作成できます。
typedef struct thread_info {
pthread_t thread;
//...
} thread_info;
//...
tinfo = malloc(sizeof(thread_info) * NUMBER_OF_THREADS);
//...
pthread_create (&tinfo[i].thread, NULL, handler, (void*)&tinfo[i]);
//...
void *handler(void *targs) {
thread_info *tinfo = targs;
// here you get the thread id with tinfo->thread
}
この方法で書くこともでき、それは同じことをします。例:
for(int i=0;i < total; i++)
{
pthread_join(pth[i],NULL);
cout << "SUM of thread id " << pth[i] << " is " << args[i].sum << endl;
}
このプログラムは、pthread_tの配列を設定し、それぞれの合計を計算します。つまり、スレッドIDを持つ各スレッドの合計を出力しています。
プラットフォームに依存しない方法(c ++ 11以降)は次のとおりです。
#include <thread>
std::this_thread::get_id();
pthread_t
。Macではポインタになり、Linuxでは整数になります。またtop
、たとえば表示される可能性のある「ネイティブ」IDも反映されません。知っておくべきことですが、用途によっては問題ないかもしれません。