it-swarm.com.ru

Если потоки имеют одинаковый 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 потока)?
84
SPSN

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

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

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

Когда поток запускает другой thread,, этот запущенный поток получает свой собственный 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, что и поток, который его запустил.


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

237
paxdiablo

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

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

2
Jesus Ramos