c ++ 11は現在のスレッドIDを取得する可能性がありますが、整数型にキャストできません:
cout<<std::this_thread::get_id()<<endl;
出力:139918771783456
cout<<(uint64_t)std::this_thread::get_id()<<endl;
エラー:タイプ「std :: thread :: id」からの無効なキャストは「uint64_t」を入力します他のタイプと同じ:タイプ「std :: thread :: id」からの無効なキャストは「uint32_t」を入力します
整数スレッドIDを取得するために、ポインターキャストを実行したくありません。それを行うための何らかの合理的な方法(私はそれが移植可能になりたいので標準です)はありますか?
移植可能なソリューションは、生成された独自のIDをスレッドに渡すことです。
int id = 0;
for(auto& work_item : all_work) {
std::async(std::launch::async, [id,&work_item]{ work_item(id); });
++id;
}
std::thread::id
タイプは、比較にのみ使用され、算術には使用されません(つまり、缶に書かれているようにidentifier)。 operator<<
によって生成されるテキスト表現でさえ未指定であるため、数値の表現であることに頼ることはできません。
独自のIDにstd::thread::id
値のマップを使用し、IDを直接渡すのではなく、スレッド間で(適切な同期を使用して)このマップを共有することもできます。
あなたはただする必要があります
std::hash<std::thread::id>{}(std::this_thread::get_id())
size_t
を取得します。
cppreference から:
std::hash
クラスのstd::thread::id
のテンプレート特化により、ユーザーはスレッドの識別子のハッシュを取得できます。
別のID(アイデア?^^)は、文字列ストリームを使用することです。
std::stringstream ss;
ss << std::this_thread::get_id();
uint64_t id = std::stoull(ss.str());
そして、物事がうまくいかない場合に例外が必要ない場合は、try catchを使用してください...
1つのアイデアは、スレッドローカルストレージを使用して変数を格納することです(スレッドローカルストレージの規則に準拠している限り、どのタイプでもかまいません)。次に、その変数のアドレスを「スレッドID」として使用します。明らかに、算術演算は意味がありませんが、整数型になります。
後世の場合:pthread_self()
は_pid_t
_を返し、posixです。これは、ポータブルの定義のためにポータブルです。
gettid()
、ほぼ確実に移植性はありませんが、GDBフレンドリーな値を返します。
私はこれがどれほど速いか本当に知りませんが、これは私がゲスト化することに成功した解決策です:
const size_t N_MUTEXES=128;//UINT_MAX,not 128 for answer to my original question
hash<std::thread::id> h;
cout<<h(std::this_thread::get_id())%N_MUTEXES<<endl;
繰り返しますが、構造体へのポインタを取得し、それをunsigned intまたはuint64_tにキャストすることが答えだと考え始めています...編集:
uint64_t get_thread_id()
{
static_assert(sizeof(std::thread::id)==sizeof(uint64_t),"this function only works if size of thead::id is equal to the size of uint_64");
auto id=std::this_thread::get_id();
uint64_t* ptr=(uint64_t*) &id;
return (*ptr);
}
int main()
{
cout<<std::this_thread::get_id()<<" "<<get_thread_id()<<endl;
}
地獄のような問題を防ぐためのstatic_assert :)書き換えは、この種のバグを見つけるよりも簡単です。 :)
thread::native_handle()
はthread::native_handle_type
のtypedefであるlong unsigned int
を返します。
スレッドがデフォルトで構成されている場合、native_handle()は0を返します。OSスレッドが接続されている場合、戻り値はゼロ以外です(POSIXではpthread_tです)。
thread_idの使用目的によって異なります。使用できます:
std::stringstream ss;
ss << std::this_thread::get_id();
uint64_t id = std::stoull(ss.str());
これにより、処理時に一意のIDが生成されます。ただし、制限があります。同じプロセスの複数のインスタンスを起動し、それぞれがスレッドIDを共通ファイルに書き込む場合、thread_idの一意性は保証されません。実際、重複する可能性が非常に高くなります。この場合、次のようなことができます:
#include <sys/time.h>
timespec ts;
clock_gettime(CLOCK_REALTIME, &ts);
uint64_t id = (ts.tv_sec % 1000000000) * 1000000000 + ts.tv_nsec;
これで、システム全体で一意のスレッドIDが保証されます。
このようにして、動作するはずです:
std::stringstream ss;
ss << std::this_thread::get_id();
int id = std::stoi(ss.str());
ライブラリsstreamを含めることを忘れないでください
このソリューションは誰かに役立つかもしれません。初めてim main()
と呼びます。警告:names
は無期限に増加します。
std::string currentThreadName(){
static std::unordered_map<std::thread::id,std::string> names;
static std::mutex mtx;
std::unique_lock<std::mutex> lock(mtx);
auto id = std::this_thread::get_id();
if(names.empty()){
names[id] = "Thread-main";
} else if(names.find(id) == names.end()){
std::stringstream stream;
stream << "Thread-" << names.size();
names[id] = stream.str();
}
return names[id];
}
Thread :: get_id()を使用しない主な理由は、単一のプログラム/プロセスで一意ではないためです。これは、最初のスレッドが終了すると、idを2番目のスレッドに再利用できるためです。
これは恐ろしい機能のように見えますが、c ++ 11の機能です。