C ++ 11 имеет некоторое представление о потоках. Например, он определяет новый спецификатор хранилища thread_local
, и указывает, что для переменных с этим спецификатором хранения «имеется отдельный объект или ссылка на поток» [basic.stc.thread].
Что считается «нитью» для этой цели? Это только потоки, созданные с использованием стандартной библиотеки потоков (то есть те, которые представлены std::thread
объекты)? Как насчет потоков, созданных другими способами (например, с помощью pthreads непосредственно в Linux)? Что делать, если я использую библиотеку, которая обеспечивает потоки пользовательского пространства — каждый из них получает свои собственные копии thread_local
объекты (я не вижу, как это можно реализовать)?
Если ответ «это определяется реализацией, то считается потоком для таких целей, как thread_local
«Кто-нибудь может привести пример того, как одна известная реализация определяет это?
Только компоненты из потока поддерживают библиотеку из-за этих кавычек или main
который стандарт заявляет работает в своем собственном потоке выполнения.
1 В следующих подпунктах описаны компоненты для создания и управления темы (1.10), выполнять взаимное исключение и передавать условия и значения между потоками, как показано в таблице 148.
Ссылка на 1.10 подразумевает, что речь идет о потоках.
1 Поток выполнения (также известный как поток) — это отдельный поток управления в программе, включая начальный …
Поэтому мне кажется потоки ссылаются только на потоки stdlib (имеется в виду std :: thread и все, что библиотека поддержки потоков делает внутри). Конечно thread_local
во многих случаях это может привести к работе с собственными потоками (особенно, если учесть, что в конкретной системе у вас обычно нет более одного выбора для реализации потоков), но, насколько я могу судить, стандарт не дает никаких гарантий.
C ++ 11 §1.10 / 1 определяет термины:
нить исполнения (также известный как нить) представляет собой единый поток управления в программе, включая начальный вызов определенной функции верхнего уровня и рекурсивно включающий каждый вызов функции, впоследствии выполняемый потоком. [ Замечания: Когда один поток создает другой, начальный вызов функции верхнего уровня нового потока выполняется новым потоком, а не создающим потоком. — конечная нота ]
Выделенные курсивом термины указывают на то, что это является окончательным. Можно утверждать, что это определение математически несовершенно, потому что каждый вызов функции определяет новый поток, но это, очевидно, неправильно. Они имеют в виду максимальный единый поток управления, в противном случае ненормативная заметка отменяет действие нормативного «рекурсивно включающего» текста.
С точки зрения основного языка, это просто случайность того, что std::thread
вызывает существование такой вещи.
Что делать, если я использую библиотеку, которая обеспечивает потоки пользовательского пространства — каждый из них получает свои собственные копии
thread_local
объекты (я не вижу, как это можно реализовать)?
Нет возможности написать такую библиотеку без вызовов ядра. По всей вероятности, все потоки в вашем процессе уже представлены высокоуровневой абстракцией, такой как pthreads, просто чтобы удовлетворить ядро. Стандартная библиотека C ++, скорее всего, написана против нативной библиотеки потоков, чтобы «просто работать» без дополнительного клея.
Например, thread_local
объекты инициализируются при первом обращении, а не при запуске каждого нового потока, поэтому компилятору просто нужно вставить запрос, основанный на pthread_self
получить доступ и, возможно, инициализировать. Инициализация будет регистрировать деструктор с pthread_cleanup
объект.
Здесь определяется реализация, совместима ли ранее существующая нативная библиотека с C ++. Предположим, что они предоставляют это, и это то, что клиенты, как правило, хотят, все остальные библиотеки потоков, созданные поверх него, будут автоматически совместимы, исключая какой-либо другой конфликт.
Стандарт не описывает, как ведут себя потоки, создаваемые другими библиотеками и системными вызовами. Что касается стандарта, то они не определены в своем поведении. В самом C ++ нет другого способа создать несколько потоков: такие библиотеки или системные вызовы делают вещи, которые не стандартизированы стандартом C ++.
Теперь каждая такая библиотека и системный вызов будут вести себя так, как определено их собственными спецификациями. Довольно часто C ++ std::thread
будет даже построен поверх таких библиотек или системных вызовов. Как именно работает взаимодействие, не указано.