Печать std::this thread::get id() дает "thread:: id неисполняемого потока"?

это работало отлично (и тогда инопланетяне, должно быть, взломали мой компьютер):

#include <thread>
#include <iostream>

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

    return 0;
}

и теперь он печатает thread::id of a non-executing thread.

ideone.com печатает некоторые ID, но интересно, что могло вызвать такое поведение на моей платформе.

$ 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

какие идеи?


EDIT: Ну.. когда я добавлю

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

и строки печатают тот же идентификатор, но когда я удаляю его, результат остается тем же - " не выполняется нить."

2 ответов


это побочный эффект функции glibc, фиксированной в 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.

если вы явно ссылаетесь на pthreads (-pthread или -lpthread) тогда ваша программа будет вести себя так, как ожидалось.

как ни странно, в моей системе, добавив вызов pthread_self (до или после вызова std::this_thread::get_id() не изменяет поведение:

0
thread::id of a non-executing thread

это может быть специфичное для Ubuntu поведение, связывающее pthreads автоматически, если pthread_self называется, но это кажется немного странным. Обратите внимание, что std::this_thread::get_id() звонки pthread_self через слабую ссылку (сама через __gthread_self).


стандарт фактически не определяет, что this_thread::get_id собирается вернуться. Все, что он говорит:

возвращает: объект типа thread:: id that однозначно определяет текущий поток выполнения. Никакой другой поток выполнения имеет этот id и этот поток выполнения всегда должны иметь этот id. Этот возвращаемый объект не должен сравниваться равным построенному по умолчанию поток:: id.

это условие выполняется с вашим выходом, так что все в порядке.

кстати, не путайте thread_id возвращено this_thread::get_id с числовым идентификатором потока, возвращенным std::thread::get_id(). thread_id главное использование для сравнения и используется в ассоциативных контейнерах, прямо не анализировался или напечатано.