How to get integer stream id in C ++ 11

C ++ 11 has the ability to get the current stream identifier, but it does not lend itself to an integer type:

cout<<std::this_thread::get_id()<<endl; 

: 139918771783456

 cout<<(uint64_t)std::this_thread::get_id()<<endl; 

error: invalid cast from type 'std :: thread :: id for input' uint64_t the same for other types: invalid cast from type 'std :: thread :: id for input' uint32_t

I really don't want to do casting with a pointer to get an integer stream id. Is there a reasonable way (standard because I want it to be portable) to do this?

+75
c ++ multithreading c ++ 11
Sep 15 '11 at 2:00
source share
11 answers

A portable solution is to pass your own identifiers to the stream.

 int id = 0; for(auto& work_item : all_work) { std::async(std::launch::async, [id,&work_item]{ work_item(id); }); ++id; } 

The std::thread::id should be used only for comparison, and not for arithmetic (i.e., as the bank says: identifier). Even its textual representation created by operator<< is not specified, so you cannot rely on the fact that it is a number.

You can also use the std::thread::id value map for your own identifier and share this map (with proper synchronization) between threads, rather than passing the identifier directly.

+29
Sep 15 '11 at 2:33 p.m.
source share

You just need to do

 std::hash<std::thread::id>{}(std::this_thread::get_id()) 

to get size_t .

Out of context :

A specialization of the std::hash std::thread::id for std::thread::id allows users to obtain hashes of thread identifiers.

+73
Apr 04 '13 at 14:19
source share

Another id (idea? ^^) would be using stringstreams:

 std::stringstream ss; ss << std::this_thread::get_id(); uint64_t id = std::stoull(ss.str()); 

And use try catch if you do not want the exception to be in case everything went wrong ...

+22
May 28 '14 at 8:43
source share

One idea would be to use a local thread store to store a variable - it doesn't matter what type, if it complies with the local stream store rules - then use the address of that variable as your “stream identifier." "Obviously, any arithmetic would not make sense but it will be an integral type.

For posterity: pthread_self() returns a pid_t and is posix. It is portable to define a portable device.

gettid() is almost certainly not portable, but it returns a friendly GDB value.

+6
Dec 08 '11 at
source share

I really don't know how fast this happens, but this is the solution I managed to execute:

 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; 

Again, I'm starting to think that getting a pointer to a structure and dropping it to unsigned int or uint64_t is the answer ... EDIT:

 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 to prevent hellish problems :) Rewriting is easy compared to finding this kind of error. :)

+4
Sep 15 '11 at 16:39
source share

Thus, you should work:

 std::stringstream ss; ss << std::this_thread::get_id(); int id = std::stoi(ss.str()); 

Remember to enable the sstream library

+3
Sep 07 '17 at 9:33 on
source share

thread::native_handle() returns thread::native_handle_type , which is a typedef for long unsigned int .

If the thread was created by default, native_handle () returns 0. If the OS thread is attached to it, the return value is nonzero (this is pthread_t in POSIX).

+3
Jan 03 '18 at 8:41
source share

it depends on what you want to use thread_id for; you can use:

 std::stringstream ss; ss << std::this_thread::get_id(); uint64_t id = std::stoull(ss.str()); 

This will create a unique identifier with your process; but there is a limitation: if you run several instances of the same process, and each of them writes its thread identifiers to a common file, the uniqueness of thread_id is not guaranteed; in fact, most likely you will have overlaps. In this case, you can do something like:

 #include <sys/time.h> timespec ts; clock_gettime(CLOCK_REALTIME, &ts); uint64_t id = (ts.tv_sec % 1000000000) * 1000000000 + ts.tv_nsec; 

You are now guaranteed unique flow identifiers throughout the country.

+2
Jul 27 '17 at 9:24
source share

Maybe this solution will be useful for someone. Name it for the first time im main() . Warning: names grows endlessly.

 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]; } 
+1
Apr 19 '19 at 20:27
source share

Another alternative:

 #include <atomic> static std::atomic<unsigned long long> thread_counter; unsigned long long thread_id() { thread_local unsigned long long tid = thread_counter++; return tid; } 

The generated code for this g ++ function in the x86 64-bit version is simple:

 _Z9thread_idv: cmp BYTE PTR fs:_ZGVZ9thread_idvE3tid@tpoff, 0 je .L2 mov rax, QWORD PTR fs:_ZZ9thread_idvE3tid@tpoff ret .L2: mov eax, 1 lock xadd QWORD PTR _ZL14thread_counter[rip], rax mov BYTE PTR fs:_ZGVZ9thread_idvE3tid@tpoff, 1 mov QWORD PTR fs:_ZZ9thread_idvE3tid@tpoff, rax ret _ZGVZ9thread_idvE3tid: .zero 8 _ZZ9thread_idvE3tid: .zero 8 

Those. one branch without any synchronization, which will be correctly predicted, with the exception of the first function call. After that, just one memory access without synchronization.

+1
Sep 18 '19 at 8:18
source share

The main reason not to use thread :: get_id () is that it is not unique to a single program / process. This is because the identifier can be reused for the second thread as soon as the first thread completes.

This seems like a terrible feature, but it is what is in C ++ 11.

0
Aug 23 '19 at 15:09
source share



All Articles