커널 소스 코드: do_fork()의 parent_tidptr 및 child_tidptr은 무엇입니까?

커널 소스 코드: do_fork()의 parent_tidptr 및 child_tidptr은 무엇입니까?

위의 내용에 대해서는협회parent_tidptr새로운 프로세스를 생성한다는 것은 무엇을 의미합니까 child_tidptr?do_fork()

답변1

먼저 원시 시스템 호출 인터페이스를 살펴보겠습니다. 아키텍처에 따라 조금씩 다르지만 x86-64에서는 다음과 같습니다.

   long clone(unsigned long flags, void *child_stack,
              int *ptid, int *ctid,
              unsigned long newtls);

ptid은(는 ) ctid귀하의 것이고 . 이제 무엇을 보자parent_tidptrchild_tidptrclone(2)매뉴얼 페이지는 다음과 같이 말해야 합니다:

   CLONE_CHILD_CLEARTID (since Linux 2.5.49)
          Erase  the  child  thread  ID  at the location ctid in
          child memory when the child exits, and do a wakeup  on
          the  futex  at that address.

   CLONE_CHILD_SETTID (since Linux 2.5.49)
          Store  the child thread ID at the location ctid in the
          child's memory.

   CLONE_PARENT_SETTID (since Linux 2.5.49)
          Store  the child thread ID at the location ptid in the
          parent's memory. 

이러한 플래그는 주로 스레드 라이브러리 구현을 위해 설계되었습니다. NPTL의 구현을 살펴보면pthread_create()glibc 내부에서 마침내 코드를 찾았습니다.sysdeps/unix/sysv/linux/createthread.cclone()CLONE_PARENT_SETTIDCLONE_CHILD_CLEARTID를 포함하는 전화를 겁니다 flags.

해당 호출에서 및 매개변수 clone()도 볼 수 있습니다 .ptidctid같은 주소를 가리키세요. (POSIX 스레드는 주소 공간을 공유한다는 점을 기억하세요. 이는 플래그를 통해 수행됩니다 clone() CLONE_VM.)

자, 여기서 무슨 일이 일어나고 있는지 살펴보겠습니다.

  • CLONE_PARENT_SETTID커널 스레드 ID가 사용자 공간 어딘가에 저장되어 있는지 확인하는 데 사용됩니다. 스레드 구현의 사용자 공간 측에서는 이 스레드 ID를 알아야 합니다.
  • CLONE_CHILD_CLEARTIDTerminates에 의해 생성된 스레드가 동일한 위치를 지우는(즉, 제로화) 데 사용됩니다 clone().

한걸음 더 나아가자...

ptid전달/반환된 스레드 ID ctid는 다음과 같습니다.아니요POSIX 스레드 ID( )와 동일 pthread_t하지만 NPTL과 같은 1:1 스레드 구현에서는 커널 스레드 ID와 POSIX 스레드 ID가 일대일로 대응됩니다. 커널 스레드 ID는 Linux를 사용하는 것과 동일합니다.gettid()부르다. 이는 또한 clone()시스템 호출 반환 값으로 반환되는데, 이는 다음과 같은 질문을 제기합니다. 왜 ptid/ 가 필요한가요 ctid? 문제는 사용자 공간 측면에서 상황이 다음과 같다는 것입니다.

tid = clone(...);

tid사용자 공간 스레드 구현 관점에서 볼 때 여기에는 경쟁이 있습니다.뒤쪽에 clone()반품. 이는 새 스레드가 작업(예: 종료)을 수행하기 전에 사용자 공간 스레딩 라이브러리에서 이 정보를 요구하는 경우 일부 문제가 발생할 수 있음을 의미합니다. CLONE_PARENT_SETTID새 스레드 ID가 가리키는 위치에 배치되었는지 확인하는 데 사용됩니다 .ptid 앞으로 clone()스레딩 라이브러리가 이러한 경쟁 조건을 피할 수 있도록 반환합니다. ( CLONE_CHILD_SETTID비슷한 효과로 사용할 수도 있습니다.)

CLONE_CHILD_CLEARTIDClear ptid/를 사용하는 이유 ctid는 방법을 제공하기 위해서입니다.pthread_join()다른 스레드를 호출하면 해당 스레드가 종료되었음을 알 수 있습니다. 기본적으로 ptid/ ctid위치는 다음과 같이 사용됩니다.퓨텍스,게다가futex()시스템 호출은 해당 위치의 정수가 변경되기를 기다리면서 차단하는 데 사용됩니다. (자세한 내용은 조금 복잡하지만 grepglibc 소스 코드에서 중화를 사용하기 위한 것입니다. 결국에는 연산이 발생합니다. 위의 대상 주소에서 futex wakeup을 기억하세요.)lll_wait_tidlll_futex_waitFUTEX_WAITCLONE_CHILD_CLEARTID

답변2

tid"스레드 ID"를 나타냅니다. 매개변수 parent_tidptrchild_tidptr포인트는 각각 상위 프로세스의 주소 공간과 하위 프로세스의 주소 공간에 있는 사용자 공간 메모리를 가리킵니다. 새로 생성된 스레드의 ID는 포인터가 가리키는 int 변수에 저장됩니다.

자세한 내용은 다음을 참조하세요.clone(2)맨페이지.

관련 정보