Подтвердить что ты не робот

Если потоки разделяют один и тот же 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 (thread ID)?
4b9b3361

Ответ 1

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

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

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

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

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

Следующая иерархия потоков может помочь 1:

                      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, что и поток, который его запускал.


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

Ответ 2

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

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

Ответ 3

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