2012-11-21 2 views
0

현재 clone()을 사용하여 스레딩을 구현하려고합니다. 질문은 각 스레드가 동일한 메모리 공간을 사용하고 주어진 스레드에서 호출하는 각 함수에서 각 스레드가 동일한 함수가 호출 될 때 다른 부분의 메모리를 사용하거나이 작업을 수행하기 위해 수행 할 작업이 있습니까?클론을 사용하여 스레딩 함수 및 변수 공간

답변

0

각 스레드는 전체적으로 동일한 메모리 맵을 사용하지만 함수 호출을 위해 별도의 스레드 로컬 스택을 사용합니다. 다른 스레드가 동일한 함수 (동일한 실행 메모리 위치에 존재 함)를 호출하면 모든 로컬 변수는 함수에 대한 입력시 스택에 할당되므로/필요에 따라 각 스레드는 공유되지 않으며 각 스레드마다 고유 한 기본적으로 스택. 정적/전역 메모리에

참조 (즉, 아무것도 clone를 호출 한 후 이러한 스레드/볼에 전달 힙 또는 mmap 메모리 영역에 전역 또는 참조로, 스레드 로컬 스택에 할당하고, 일반적으로하지 , 전체 메모리 맵과 프로세스 컨텍스트 자체는 물론 공유되고 멀티 스레딩 문제의 일반적인 호스트 (예 : 공유 상태 동기화)의 영향을받습니다.

clone을 호출하기 전에이 스레드 로컬 스택 공간을 직접 설정해야합니다. 맨 페이지에서 :

child_stack 인수는 자식 프로세스에 의해 사용되는 스택의 위치를 ​​지정합니다. 자식 프로세스와 호출 프로세스가 메모리를 공유 할 수 있기 때문에 하위 프로세스가 호출 프로세스와 동일한 스택 에서 실행할 수 없습니다. 따라서 호출 프로세스는 자식 스택의 메모리 공간을 으로 설정하고이 공간의 포인터를 clone()으로 전달해야합니다. Linux를 실행하는 모든 프로세서 (HP PA 프로세서 제외)에서 스택 수가 증가하므로 child_stack은 일반적으로 하위 스택에 대해 설정된 메모리 공간의 최상위 주소 을 가리 킵니다.

child_stack 매개 변수는 clone의 두 번째 인수입니다. clone을 통해 생성 된 각 하위 스레드가 스택에 대해 별도의 메모리 덩어리를 수신하는 것은 호출자 (즉, 상위 스레드)의 책임입니다.

이 스레드 로컬 스택 메모리 영역을 할당하고 설정하는 것은 결코 간단하지 않습니다. 페이지 정렬 (시작 주소는 4K 경계에 있음), 페이지 크기 (4K)의 배수, 크기가 넉넉한 (스레드가 2 개 밖에없는 경우 2MB가 안전 할 경우) 가드 (guard) "섹션을 참조하십시오. 스택 가드는 액세스 권한이없는 페이지의 일부입니다. 읽기가없고 쓰기가 없습니다. 스레드가 동적으로 스택 크기를 초과하면 나머지 가상 메모리 주소 공간을 보호하기 위해 주 스택 영역을 따라 가야합니다 (예 : 묶음 재귀 또는 로컬 변수로 매우 큰 임시 버퍼가있는 함수) 스택 가드 영역으로 계속 확장하려고 시도합니다. 스레드가 교활하게 손상되는 대신 SIGSEGV를 즉시 제공하므로 실패 할 것입니다. 스택 가드는 기술적으로 선택 사양입니다. posix_memalign은 스택을 할당하는 데 아마도 mmap을 사용해야합니다.

모두 제가 물어야합니다 : 왜 clone과 함께 스레딩을 구현하려고합니까? 여기 몇 가지 매우 어려운 문제가 있으며 POSIX 스레딩 라이브러리가이를 해결했습니다 (이식성있는 방식으로).clone의 세분화 된 컨트롤 인 경우 pthread_attr_* 함수를 체크 아웃하십시오. 그들은 거의 모호하지 않은 모든 유스 케이스를 다루고있다. (예전의 토론에서 당신이 원하는대로 자신 만의 스택을 할당 할 수 있도록 허용한다. 나는 그렇지 않다고 생각한다.) 다른 것들 중에서도 매우 성능이 좋은 일반 리눅스 구현은 clone과 스레딩과 관련된 다양한 종류의 다른 가금 시스템 호출을 완벽하게 감 쌉니다. 많은 경우 C 라이브러리 래퍼가 없으며 syscall을 통해 호출해야합니다. 그것은 모두 당신이하고 싶은 것에 따라 다릅니다.

+0

솔직히 말해서, 나는 pthreads를 사용해야한다고 결론을 내 렸습니다. 그렇습니다. 동기 부여의 일부는 제어이며, 일반적으로 스레드와 같은 내 자신의 기능을 쓰는 것을 선호합니다. 내가 할 수있는 곳. – jatos