Если потоки имеют одинаковый PID, как их можно идентифицировать?

У меня есть запрос, связанный с реализацией потоков в 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 ответа

Четыре потока будут иметь одинаковый 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 не различает процессы и потоки.

Другие вопросы по тегам