10

This used to work perfectly fine (and then aliens must have hacked my PC):

#include <thread>
#include <iostream>

int main()
{
    std::cout << std::this_thread::get_id() << std::endl;

    return 0;
}

and now it prints thread::id of a non-executing thread.

ideone.com prints some ID, but it's interesting what may have caused this behavior on my platform.

$ uname -a
Linux xxx 3.13.0-77-generic #121-Ubuntu SMP Wed Jan 20 10:50:42 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux

Any ideas?


EDIT: Well.. when I add

std::cout << pthread_self() << std::endl;

both lines print the same ID, but when I remove it, the result is still the same - "non-executing thread".

Kiril Kirov
  • 37,467
  • 22
  • 115
  • 187

2 Answers2

9

It's a side-effect of a glibc feature, fixed in https://gcc.gnu.org/bugzilla/show_bug.cgi?id=57060:

// For the GNU C library pthread_self() is usable without linking to
// libpthread.so but returns 0, so we cannot use it in single-threaded
// programs, because this_thread::get_id() != thread::id{} must be true.

If you explicitly link against pthreads (-pthread or -lpthread) then your program will behave as expected.

Oddly enough, on my system, adding a call to pthread_self (before or after the call to std::this_thread::get_id() does not change behavior:

0
thread::id of a non-executing thread

This may be an Ubuntu-specific behavior, linking pthreads automatically if pthread_self is called, but it seems a bit odd. Note that std::this_thread::get_id() calls pthread_self via a weak reference (itself via __gthread_self).

ecatmur
  • 152,476
  • 27
  • 293
  • 366
  • Oh, that's brilliant, exactly what I wanted to understand! And yeah, I'm positive that this is exactly what have happend to me - the linkage with `pthread`. Thank you :) – Kiril Kirov Apr 01 '16 at 17:02
2

Standard does not actually define what the this_thread::get_id is going to return. All it says is:

Returns: An object of type thread::id that uniquely identifies the current thread of execution. No other thread of execution shall have this id and this thread of execution shall always have this id. The object returned shall not compare equal to a default constructed thread::id.

This condition is met with your output, so everything is in order.

By the way, do not confuse thread_id returned by this_thread::get_id with numerical thread id returned by std::thread::get_id(). thread_id main usage is to be compared and used in associative containers, not directly introspected or printed.

SergeyA
  • 61,605
  • 5
  • 78
  • 137
  • `std::thread::get_id()` returns the same `std::thread::id` type as `std::this_thread::get_id()`. – Jeremy Jul 05 '16 at 16:32