위의 내용에 대해서는협회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_tidptr
child_tidptr
clone(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.c
clone()
CLONE_PARENT_SETTID
및 CLONE_CHILD_CLEARTID
를 포함하는 전화를 겁니다 flags
.
해당 호출에서 및 매개변수 clone()
도 볼 수 있습니다 .ptid
ctid
같은 주소를 가리키세요. (POSIX 스레드는 주소 공간을 공유한다는 점을 기억하세요. 이는 플래그를 통해 수행됩니다 clone()
CLONE_VM
.)
자, 여기서 무슨 일이 일어나고 있는지 살펴보겠습니다.
CLONE_PARENT_SETTID
커널 스레드 ID가 사용자 공간 어딘가에 저장되어 있는지 확인하는 데 사용됩니다. 스레드 구현의 사용자 공간 측에서는 이 스레드 ID를 알아야 합니다.CLONE_CHILD_CLEARTID
Terminates에 의해 생성된 스레드가 동일한 위치를 지우는(즉, 제로화) 데 사용됩니다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_CLEARTID
Clear ptid
/를 사용하는 이유 ctid
는 방법을 제공하기 위해서입니다.pthread_join()
다른 스레드를 호출하면 해당 스레드가 종료되었음을 알 수 있습니다. 기본적으로 ptid
/ ctid
위치는 다음과 같이 사용됩니다.퓨텍스,게다가futex()
시스템 호출은 해당 위치의 정수가 변경되기를 기다리면서 차단하는 데 사용됩니다. (자세한 내용은 조금 복잡하지만 grep
glibc 소스 코드에서 중화를 사용하기 위한 것입니다. 결국에는 연산이 발생합니다. 위의 대상 주소에서 futex wakeup을 기억하세요.)lll_wait_tid
lll_futex_wait
FUTEX_WAIT
CLONE_CHILD_CLEARTID
답변2
tid
"스레드 ID"를 나타냅니다. 매개변수 parent_tidptr
및 child_tidptr
포인트는 각각 상위 프로세스의 주소 공간과 하위 프로세스의 주소 공간에 있는 사용자 공간 메모리를 가리킵니다. 새로 생성된 스레드의 ID는 포인터가 가리키는 int 변수에 저장됩니다.
자세한 내용은 다음을 참조하세요.clone(2)
맨페이지.