2010-11-24 8 views
1

스레드 풀에서 얻은 스레드의 프로세서 선호도를 설정할 수 있는지 궁금합니다. 특히 스레드는 TimerQueue API를 사용하여 얻습니다.이 API는 정기적 인 작업을 구현하는 데 사용됩니다.SetThreadAffinity 풀링 된 스레드의 마스크

사이드 노트로 :주기적인 작업을 구현하는 가장 쉬운 방법은 TimerQueues입니다 만, 일반적으로 이러한 작업은 오래 사용하는 것이므로 전용 스레드를 사용하는 것이 더 적절할 수 있습니다. 또한 다양한 정기적 인 작업을 동기화하기 위해 semapores 및 mutex와 같은 동기화 primites를 사용해야 할 것으로 예상됩니다. 풀링 된 스레드가 이에 적합합니까?

감사합니다.

EDIT1 : 레오는 위의 질문에서 실제로 두 가지가 느슨하게 관련된 것임을 지적했습니다. 첫 번째는 풀링 된 스레드의 프로세서 선호도와 관련이 있습니다. 두 번째 질문은 TimerQueue API에서 얻은 풀링 된 스레드가 동기화 개체와 관련하여 수동으로 생성 된 스레드와 똑같이 동작하는지 여부와 관련됩니다. 나는이 두 번째 질문을 별개의 주제로 옮길 것이다.

답변

2

이렇게하는 경우 스레드를 풀로 다시 릴리스 할 때마다 어떻게 돌아 왔는지 확인하십시오. 당신이 그 스레드를 소유하고 있지 않기 때문에 그것들을 사용하는 다른 코드는 다른 요구 사항/가정을 가질 수 있습니다.

실제로이 작업을 수행해야합니까? 프로세서 선호도를 설정하는 것은 매우 드문 일입니다. (나는 필자가 작성한 모든 것에 이것을 할 필요가 없다고 생각한다.)

스레드 선호도는 두 가지 전혀 다른 것을 의미 할 수있다. (. 감사의이 지적 내 원래의 대답 의견 bk1e하는 나 자신을 실현하지 않았다.)

  1. 내가 프로세서 선호도 부를 것이다 : 스레드가 온 지속적으로 실행해야 동일한 프로세서. 이것은 SetThreadAffinityMask가 다루는 것이며 코드가 신경 쓰는 일은 매우 드뭅니다. (일반적으로 고성능 코드에서 CPU 캐싱과 같은 매우 낮은 수준의 문제로 인해 발생합니다. 일반적으로 OS는 동일한 CPU에 스레드를 유지하기 위해 최선을 다할 것이며 대개 강제로 비효율적입니다.)

  2. 스레드 선호도 : 개체가 스레드 로컬 저장소 (또는 스레드가 액세스 한 스레드에 연결된 다른 상태)를 사용하며 일련의 작업이 동일한 스레드에서 수행되지 않으면 잘못된 작업이 수행됩니다.

# 1과 # 2를 혼동시키는 것처럼 들릴 수도 있습니다. 콜백이 실행 중일 때 스레드 자체는 으로 변경되지 않습니다.. 스레드가 실행되는 동안 CPU 사이에서 점프 할 수 있지만 이는 정상적인 것이며 매우 특별한 경우를 제외하고는 걱정할 필요가 없습니다.

뮤텍스, 세마포어 등은 스레드가 CPU간에 점프하는지 상관하지 않습니다.

콜백이 스레드 풀에서 여러 번 실행되는 경우 일반적으로 풀이 사용되는 방법에 따라 동일한 스레드가 사용될 것이라고 보장 할 수 없습니다. 즉, 콜백이 스레드간에 이동할 수는 있지만 실행 중일 때는 그렇지 않습니다. 다시 실행될 때마다 스레드 만 변경할 수 있습니다.

일부 동기화 개체 입니다. 콜백 코드가 하나의 스레드에서 실행되고 여전히 해당 개체에 대한 잠금을 보유하고 있다고 생각하면 다른 스레드에서 다시 실행됩니다. (어떤 종류의 동기화 객체를 사용 하느냐에 따라 다르긴하지만, 첫 번째 쓰레드는 여전히 두 번째 쓰레드가 아니라 잠금을 유지할 것입니다. 어떤 것은 신경 쓰지 않습니다.) # 1이 아닙니다. 그것은 # 2이고, 당신이 처리 할 SetThreadAffinityMask를 사용할 것이 아닙니다.

예를 들어, Mutexes (CreateMutex)는 스레드가 소유합니다. 스레드 A에서 뮤텍스를 획득하면 스레드 A에서 뮤텍스를 해제 할 때까지 뮤텍스를 획득하려고 시도하는 다른 스레드가 차단됩니다. 스레드가 소유하지 않은 뮤텍스를 릴리스하는 오류이기도합니다. 따라서 if 귀하의 콜백은 뮤텍스를 획득 한 다음 종료되고 다른 스레드에서 다시 실행되어 거기에서 뮤텍스를 릴리스했습니다.

한편 이벤트 (CreateEvent)는 어떤 스레드가 해당 스레드를 생성, 신호 또는 소멸시키는 지 신경 쓰지 않습니다. 한 스레드에서 이벤트를 신호 한 다음 다른 스레드에서 이벤트를 재설정 할 수 있습니다. 실제로는 정상입니다.

콜백의 두 개의 개별 실행 사이에 동기화 객체를 보유하는 것도 드뭅니다 (교착 상태를 유발할 수 있습니다. 물론 그러한 일을 합법적으로 원할 수는 있지만). 그러나 아파트 스레드 COM 개체 (예를 들어)를 만든 경우 특정 스레드에서만 액세스하려는 것이 좋습니다.

+0

Microsoft의 설명서에서도 "스레드 선호도"를 사용하여 특정 스레드의 프로세서 선호도를 참조합니다. http://msdn.microsoft.com/en-us/library/ms684251%28VS.85%29.aspx – bk1e

+0

@ bk1e , 나는 고쳐 쓴다. 그렇다면 혼란 스럽습니다. :) 그것의 소리에 의해 나는 OP가 단일 CPU에서 일관되게 실행되어야하는 쓰레드보다는 단일 쓰레드에서 일관되게 사용될 필요가있는 객체에 대해 걱정한다고 생각한다. 나는 내 대답을 분명히 할 것이다. 감사! –

+0

"일부 동기화 개체는 걱정할 것입니다 [...] 일부는 상관 없습니다." 당신이 신경을 쓰는 syncronization 객체의 예를 들어 줄 수 있습니까? – Arne

0

하지 않아야합니다. 당신은 그 시점에서 실행중인 프로세서에서 현재 작업중인 스레드를 사용하기로되어 있습니다. 분명한 비효율 성과는 별개로, 스레드 풀은 완료되는 즉시 모든 스레드를 파괴하고 다음 작업을 위해 새로운 스레드를 생성합니다. 어피 니티 마스크는 실제로는 사라지지 않을 것이지만, 무작위로 사라지면 디버그하기가 더 어렵습니다.