Pthread_tがあり、そのCPUアフィニティを変更したいと思います。問題は、glibc 2.3.2を使用していることです。glibc2.3.2には pthread_setaffinity_np() がありません。ただし、pthread_setaffinity_np()自体が sched_setaffinity() のラッパーであるため、これは問題ありません。プロセスIDの代わりにスレッドIDを渡して呼び出して、任意のスレッドのアフィニティを設定できます。
[〜#〜] but [〜#〜]... sched_setaffinityが使用できるスレッドIDは、OSスレッドIDです。 gettid() システムコールから取得できます。 これは不透明タイプpthread_tとは異なり、gettid()はcurrent thread。任意のスレッドのCPUアフィニティを設定できる必要があります。
残念ながら、pthreadのプライベート部分にアクセスできません。これにより、pthread_tをstruct pthread *
にキャストしてスレッドIDを盗むことができます。私の推測では、プライベート実装に依存することは偶数moreトラブルを求めているためです。
pthread_getunique_np 関数についても読んでいますが、これは「一意の整数識別子」を返します。これは、OSスレッドIDと同等の形や形式ではないと思います。
したがって、質問:任意のpthread_tからスレッドIDを取得するにはどうすればよいですか?
pthread
sはLinuxスレッド(またはカーネルスレッド)を使用して実装する必要がなく、一部の実装は完全にユーザーレベルまたは混合であるため、pthread
sインターフェイスは以下の機能を提供しません。これらの実装の詳細にはアクセスできません(Linuxのpthread
s実装間であっても)。これらを使用するスレッドライブラリは、これを拡張機能として提供できますが、そのような機能はないようです。
スレッドライブラリの内部データ構造にアクセスする以外(当然、望まないが、プロセッサアフィニティとLinuxスレッドIDに関する仮定ではコードは移植できない)、作成時にトリックを再生できる、スレッドを作成するコードを制御する場合:
pthread_create()
にgettid()
を呼び出すエントリ関数を与えます(syscall
マクロは常にエクスポートされるとは限らないため、libc
マクロを直接使用する必要があります) VARIABLE] _)、結果をどこかに保存してから、元のエントリ関数を呼び出します。同じエントリ関数を持つ複数のスレッドがある場合、arg
引数の配列に増分ポインタをpthread_create
に渡すことができます。この引数は、スレッドを格納するために作成したエントリ関数に渡されますpthread_t
の戻り値pthread_create
を同じ順序で保存すると、pthread_t
値を指定して作成したすべてのスレッドのLinuxスレッドIDを検索できます。
このトリックが価値があるかどうかは、スレッドライブラリの内部構造にアクセスしないか、pthread_setaffinity_np
を提供するスレッドライブラリに依存するかではなく、CPUアフィニティの設定の重要性に依存します。
実際pthread_self
戻り値 pthread_t
であり、作業可能な整数のスレッドIDではありません。次のヘルパー関数は、異なるPOSIXシステム間で移植可能な方法でそれを取得します。
uint64_t gettid() {
pthread_t ptid = pthread_self();
uint64_t threadId = 0;
memcpy(&threadId, &ptid, std::min(sizeof(threadId), sizeof(ptid)));
return threadId;
}
pthread_t pthread_self()
これは、スレッドIDである現在のpthread_tを返します。これを「unsigned int」型に変換できます。
glibc 2.24では、返されるpthread_t
は、不透明なstruct pthread
へのポインタにすぎません。 nptl/descr.h
で定義を検索できます。
後でアクセスするためにスレッドからスレッドIDを書き込むことができる共有int配列を使用した簡単な回避策をお勧めします。
お役に立てば幸いです。