Если потоки имеют одинаковый PID, как их можно идентифицировать? - PullRequest
84 голосов
/ 16 февраля 2012

У меня есть запрос, связанный с реализацией потоков в Linux.

В Linux нет явной поддержки потоков. В пользовательском пространстве мы можем использовать библиотеку потоков (например, NPTL) для создания потоков. Теперь, если мы используем NPTL, он поддерживает отображение 1: 1.

Ядро будет использовать функцию clone() для реализации потоков.

Предположим, я создал 4 темы. Тогда это будет означать, что:

  • Там будет 4 task_struct.
  • Внутри task_struct будет предоставлено совместное использование ресурсов в соответствии с аргументами клонирования (CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND).

Теперь у меня есть следующий запрос:

  1. Будут ли 4 потока иметь одинаковый PID? Если кто-то может уточнить, как PID являются общими.
  2. Как идентифицируются различные темы; Есть ли какая-то концепция TID (ID потока)?

Ответы [ 3 ]

237 голосов
/ 16 февраля 2012

Четыре потока будут иметь одинаковый PID, но только при просмотре из выше. То, что вы (как пользователь) называет PID, не то, что ядро ​​(смотрит снизу) вызывает PID.

В ядре , каждый поток имеет свой собственный идентификатор, называемый PID (хотя, возможно, было бы более целесообразно называть это TID или идентификатором потока), и у них также есть TGID (группа потоков ID), который является PID потока, запустившего весь процесс.

Упрощенно, когда создается новый процесс , он выглядит как поток, в котором PID и TGID имеют одно и то же (новое) число.

Когда поток запускает другой поток , , который запустил поток, получает свой собственный PID (так что планировщик может планировать его независимо), но он наследует TGID из исходного потока.

Таким образом, ядро ​​может планировать потоки независимо от того, к какому процессу они принадлежат, в то время как процессы (идентификаторы группы потоков) сообщаются вам.

Может помочь следующая иерархия потоков (a) :

                      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 (оба установлены на одно и то же значение) при запуске нового thread (справа) дает вам новый PID, сохраняя тот же TGID, что и поток, который его запустил.


(a) Трепет от страха от моих впечатляющих графических навыков: -)

2 голосов
/ 16 февраля 2012

Потоки идентифицируются с использованием PID и TGID (идентификатор группы потоков). Они также знают, какой поток является родителем того, кто по сути дела разделяет свой PID со всеми потоками, которые он запускает. Идентификаторы потоков обычно управляются самой библиотекой потоков (например, pthread и т. Д.). Если 4 потока запущены, они должны иметь одинаковый PID. Само ядро ​​будет обрабатывать планирование потоков и тому подобное, но именно библиотека будет управлять потоками (могут ли они выполняться или нет, в зависимости от того, как вы используете методы объединения потоков и ожидания).

Примечание: это из моей памяти ядра 2.6.36. Моя работа в текущих версиях ядра находится на уровне ввода / вывода, поэтому я не знаю, изменилось ли это с тех пор.

0 голосов
/ 20 октября 2013

Linux обеспечивает системный вызов fork() традиционной функциональностью дублирования процесса.Linux также предоставляет возможность создавать потоки с помощью системного вызова clone(). Однако Linux не различает процессы и потоки.

...