2011-03-04 3 views
1

모든 스레드가 메모리 위치를 공유합니다. 예를 들어 한 스레드에서 전역 변수를 변경하면 다른 스레드에 반영됩니다. 각 스레드는 고유 한 스택을 가지고 있기 때문에 스레드 내에 생성 된 로컬 변수 변수는 고유합니다. 이 경우 스레드 특정 데이터 메커니즘을 사용하려면 이 필요한 이유는 무엇입니까? 그것은 자동 스토리지 varables 스레드 기능 안에 달성 할 수 있습니까?스레드 특정 데이터가 pthread에서 필요한 이유는 무엇입니까?

친절하게 설명 !!!.

BR 는 Rj에

+0

모든 전역 변수는 기본적으로 모든 스레드간에 공유됩니다. IIRC에서는 스레드 특정 데이터를 사용하여 변수 이름이 동일하지만 스레드 특정 인 경우를 지정할 수 있습니다. – Kakira

답변

0

예, 스택 (특정 스레드에 국부적으로 할당 힙 핸들 포함) 스레드 로컬 스토리지를 할당하는 하나의 방법이다.

3

일반 전역 변수는 스레드간에 공유됩니다. 지역 변수는 특정 함수 호출에 고유합니다. 같은 스레드에서 실행되는 여러 함수에서 (예를 들어) 볼 수 있지만 그 스레드에 고유 한 것을 원한다면 스레드 별 데이터가 원하는 것입니다.

1

이 필요하지 않습니다.하지만 다소 편리합니다. randstrtok과 같은 일부 기능은 스레드간에 공유 할 때 문제가 될 수있는 정적 저장 기간 정보를 사용합니다.

각 스레드마다 다른 순서 (따라서 시드)를 유지하려는 임의의 숫자 기능이 있다고 가정 해보십시오. 두 가지 접근법이 있습니다.

당신은 미봉책 같은 것을 사용할 수 있습니다 : 씨앗이있다

int seed; 
srand (&seed, time (NULL)); 
int r = rand_r (void *seed); 

호출자에 의해 생성 된 각각의 시간에 전달 될 수 있습니다.

아니면 오히려 더 좋은, ISO 규격을 사용할 수 있습니다 쓰레드 고유의 씨앗을 유지하기 위해 스레드 로컬 저장소를 사용

srand (time (NULL)); 
int r = rand(); 

. 마찬가지로 처리 할 문자열 내의 위치와 관련하여 strtok에서 사용하는 정보와 유사합니다.

그런 식으로 스레드 버전과 비 스레드 버전간에 코드를 변경하지 않아도됩니다.

이제 이 스레드 기능에서 정보를 작성할 수 있지만 전달되지 않고 rand 함수가 주소를 알게되는 방법은 무엇입니까? 그리고 rand을 87 스택 레벨이라 부르면 어떨까요? 포인터를 전달하는 것은 엄청나게 많은 수준입니다. 당신은 같은 것을 할 경우에도

그리고, :

void pthread_fn (void *unused) { 
    int seed; 
    rand_set_seed_location (&seed); 
    : 
} 

rand 이후 그 여전히 표준에서 코드 변경의 관계없이 스택에 얼마나 깊은의 값을 사용합니다. 그것은 작동하지만 COBOL에서 운영 체제를 작성할 수도 있습니다. 즉,

0

스레드 특정 데이터에 대한 가장 좋은 예 :-) 좋은 생각은 "errno를"입니다하지 않습니다.c 라이브러리의 일부 함수에 대한 호출이 실패하면 errno이 설정되고이를 검사하여 오류의 원인을 찾을 수 있습니다. 스레드 특정 데이터가없는 경우 오류 번호을 검사하기 전에 다른 스레드가이 특성을 멀티 스레드 환경으로 이식 할 수 없습니다.

+0

하지만 스레드 별 데이터에서 errno를 어떻게 유지합니까? – user504542

+0

glibc의 errno는 스레드 특정 데이터로 구현되며, 단지 그것을 사용합니다. 경합에 대해서는 걱정하지 마십시오. – burningice

0

일반적으로 새 API에서는 대부분의 TSD 사용을 피해야합니다. 함수가 약간의 정보를 필요로한다면, 함수에 전달되어야한다.

그러나 때로는 TSD가 API 결함을 '페이퍼 오버'해야합니다. 좋은 예가 'gmtime'입니다. 'gmtime'함수는 'gmtime'을 호출 할 때까지 유효한 구조체에 대한 포인터를 반환합니다. 하지만 이렇게하면 멀티 스레드 프로그램에서 'gmtime'을 사용하기가 너무 어렵습니다. 어떤 도서관에서 'gmtime'이라고 불렀을 때 예상치 못했을 때 구조를 파기하면 어떨까요? 한 가지 간단한 해결 방법은 구조체를 스레드별로 반환하는 것입니다. (물론 장기적인 해결책은 'gmtime_r'과 같은보다 적합한 API를 만드는 것입니다.)

새 디자인에서 TSD를 사용하는 것이 매우 합당한 경우는 자주 액세스하지 않는 정보를위한 것입니다 그러면 API가 복잡해집니다. 예를 들어 치명적인 오류가 발견되면 높은 수준의 코드에서 특정 컨텍스트 정보를 기록하는 것이 좋습니다 (어떤 클라이언트를 제공 했습니까? 어떤 명령을 보냈습니까?). 선택 사항은 기본적으로이 컨텍스트 정보를 기능에서 기능으로 전달하는 것입니다 (기능 중 일부가 사용자의 제어 범위를 벗어난 경우 항상 가능하지는 않습니다) 또는 TSD에 저장하는 것입니다.

관련 문제