Если потоки имеют одинаковый PID, как их можно идентифицировать?
У меня есть запрос, связанный с реализацией потоков в Linux.
В Linux нет явной поддержки потоков. В пользовательском пространстве мы можем использовать библиотеку потоков (например, NPTL) для создания потоков. Теперь, если мы используем NPTL, он поддерживает отображение 1:1.
Ядро будет использовать clone()
функция для реализации потоков.
Предположим, я создал 4 темы. Тогда это будет означать, что:
- Будет 4
task_struct
, - Внутри
task_struct
будет обеспечено совместное использование ресурсов в соответствии с аргументами для клонирования(CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND)
,
Теперь у меня есть следующий запрос:
- Будут ли 4 потока иметь одинаковый PID? Если кто-то может уточнить, как PID являются общими.
- Как идентифицируются различные темы; есть какая-то концепция TID (ID потока)?
3 ответа
Четыре потока будут иметь одинаковый PID, но только если смотреть сверху. То, что вы (как пользователь) называете PID, - это не то, что ядро (вид снизу) называет PID.
В ядре каждый поток имеет свой собственный идентификатор, называемый PID (хотя, возможно, имеет смысл называть его TID или идентификатором потока), и у них также есть TGID (идентификатор группы потоков), который является PID потока это начало весь процесс.
Упрощенно, когда создается новый процесс, он выглядит как поток, в котором и PID, и TGID имеют одно и то же (новое) число.
Когда поток запускает другой поток, этот запущенный поток получает свой собственный PID (так что планировщик может планировать его независимо), но он наследует TGID от исходного потока.
Таким образом, ядро может планировать потоки независимо от того, к какому процессу они принадлежат, а процессы (идентификаторы групп потоков) сообщаются вам.
Следующая иерархия потоков может помочь(а):
USER VIEW
<-- PID 43 --> <----------------- PID 42 ----------------->
+---------+
| process |
_| pid=42 |_
_/ | tgid=42 | \_ (new thread) _
_ (fork) _/ +---------+ \
/ +---------+
+---------+ | process |
| process | | pid=44 |
| pid=43 | | tgid=42 |
| tgid=43 | +---------+
+---------+
<-- PID 43 --> <--------- PID 42 --------> <--- PID 44 --->
KERNEL VIEW
Вы можете видеть, что запуск нового процесса (слева) дает вам новый PID и новый TGID (оба установлены на одно и то же значение), в то время как запуск нового потока (справа) дает вам новый PID при сохранении того же TGID как нить, которая его начала.
(а) Дрожу в страхе от моих впечатляющих графических навыков:-)
Потоки идентифицируются с использованием PID и TGID (идентификатор группы потоков). Они также знают, какой поток является родителем того, кто по сути дела разделяет свой PID с любыми потоками, которые он запускает. Идентификаторы потоков обычно управляются самой библиотекой потоков (например, pthread и т. Д.). Если 4 потока запущены, они должны иметь одинаковый PID. Само ядро будет обрабатывать планирование потоков и тому подобное, но именно библиотека будет управлять потоками (могут ли они выполняться или нет, в зависимости от того, как вы используете методы объединения потоков и ожидания).
Примечание: это из моей памяти ядра 2.6.36. Моя работа в текущих версиях ядра находится на уровне ввода / вывода, поэтому я не знаю, изменилось ли это с тех пор.
Linux предоставляют fork()
Системный вызов с традиционной функциональностью дублирования процесса. Linux также предоставляет возможность создавать потоки, используя clone()
Системный вызов Однако Linux не различает процессы и потоки.