스레드가 동일한 PID를 공유하는 경우 어떻게 식별 할 수 있습니까?


97

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) 개념이 있습니까?

답변:


273

4 개의 스레드는 동일한 PID를 갖지만 위에서 볼 때만 가능 합니다. 무엇 당신 (사용자로)는 PID를 호출하면 커널 (아래에서 찾고)는 PID를 호출하는 것이 아니다.

에서 커널, 각 스레드는 스레드의 PID입니다 (이것은 아마도 이것을 TID, 또는 스레드 ID를 호출하는 더 나을하지만) 그들은 또한 TGID (thread 그룹 ID)를 가지고 PID라는 그 자신의 ID를 가지고 그것은 전체 과정을 시작했습니다.

간단히 말해서 새 프로세스 가 생성되면 PID와 TGID가 같은 (새) 번호 인 스레드로 나타납니다.

스레드가 다른 스레드 를 시작하면 시작된 스레드는 자체 PID를 얻지 만 (스케줄러가 독립적으로 스케줄 할 수 있음) 원래 스레드에서 TGID를 상속합니다.

이런 식으로 커널은 자신이 속한 프로세스에 관계없이 스레드를 즐겁게 예약 할 수 있으며 프로세스 (스레드 그룹 ID)가보고됩니다.

다음 스레드 계층 구조가 도움이 될 수 있습니다 (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 (둘 다 동일한 값으로 설정 됨)가 제공되는 반면 새 스레드 (오른쪽) 를 시작하면 동일한 값 을 유지하면서 새 PID가 제공됨 을 알 수 있습니다. TGID를 시작한 스레드입니다.


(a) 내 인상적인 그래픽 기술 에 경외심떨기 :-)


20
참고로, www.makelinux.com/에 표시된대로 getpid()tgid :를 반환합니다 .asmlinkage long sys_getpid(void) { return current->tgid;}
Duke

6
@Duke-와, 그래서 gettgid(2)함수를 찾을 수 없었습니다 . 그리고 getpid()TID (스레드의 "PID")를 반환하지 않으며 gettid(2)들어오는 위치 가 있습니다. 이렇게하면 우리가 주 스레드에 있는지 여부를 알 수 있습니다.
Tomasz Gandor 2014

2
이것은 또 다른 흥미로운 점으로 이어집니다. 따라서 스레드와 프로세스가 커널 내에서 동일하게 처리되는 경우 (tgid와는 별개로), 결론적으로 다중 스레드 프로세스는 단일 스레드 프로세스보다 CPU 시간이 더 많을 것입니다. 우선 순위를 지정하고 어떤 이유로 든 (뮤텍스 대기 등) 중단 된 스레드가 없습니다.
Aconcagua 2015 년

1
@Aconcagua, CFS (Linux의 완전 공정한 스케줄러)는 일반적으로 그런 방식으로 작동하지만 그룹 스케줄러 확장을 사용하여 개별 작업이 아닌 특정 작업 그룹에서 공정성을 작동 할 수 있습니다. 나는 피상적 인 시선 외에는 실제로 들여다 본 적이 없습니다.
paxdiablo 2015 년

''getgrp를 ''그룹 ID 얻을
Pengcheng

2

스레드는 PID 및 TGID (스레드 그룹 ID)를 사용하여 식별됩니다. 또한 기본적으로 프로세스가 시작하는 스레드와 PID를 공유하는 스레드가 부모 인 스레드를 알고 있습니다. 스레드 ID는 일반적으로 스레드 라이브러리 자체 (예 : pthread 등)에서 관리합니다. 4 개의 스레드가 시작되면 동일한 PID를 가져야합니다. 커널 자체는 스레드 스케줄링 등을 처리하지만 라이브러리는 스레드를 관리 할 것입니다 (스레드 조인 및 대기 방법 사용에 따라 실행 가능 여부에 관계없이).

참고 : 이것은 커널 2.6.36에 대한 기억입니다. 현재 커널 버전의 작업은 I / O 계층에 있으므로 그 이후로 변경되었는지 알 수 없습니다.


-6

Linux fork()는 프로세스를 복제하는 전통적인 기능을 시스템 호출에 제공합니다 . Linux는 clone()시스템 호출을 사용하여 스레드를 생성하는 기능도 제공합니다. 그러나 Linux는 프로세스와 스레드를 구분하지 않습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.