2009-11-07 3 views
3

가짜 상황 : 클래스가 있습니다 (예 : BackgroundMagic). Start()Stop() 개의 메소드가 있습니다. 이 클래스의 작업은 하나의 스레드에 의해 수행되며 X 밀리 초마다 짧은 루프입니다.스레드를 유휴 상태로 유지하거나 죽이거나 다시 시작 하시겠습니까?

중단/시작을 관리하는 데있어 다음 중 더 나은 옵션은 무엇입니까? 어떤 도로를 가져갈 지 결정할 수 없습니다.

  1. 처음으로 Start()가 호출되면 IsBackground = true로 스레드를 초기화하고 시작하십시오. 단순한 bool 플래그를 사용하여 각 루프에서 실제로 작업을 수행할지, 아니면 잠자기 상태로 할지를 지정하십시오. 초기 초기화 후 Stop() 및 Start()가 bool 플래그를 제어하게합니다. 스레드는 응용 프로그램이 종료 될 때 IsBackground = true가되기 때문에 런타임에 의해 중지되고 정리됩니다.
  2. 의 정지시 강제로 중단/결합/중단하고 스레드를 다시 놓아 두지 않고 Start()에서 스레드를 다시 재생성하십시오.

... 또는이 작업을 수행하는 데있어 더 좋고/더 좋은 방법은 무엇입니까?

답변

1

스레드 생성은 상당히 비싸므로 표준 "산업 강도"는 플래그를 사용하여 스레드를 제어하는 ​​것입니다. 같은 아이디어에 대해 더 큰 규모의 변형을 위해 스레드 풀을 고려해보십시오. 아파치는 많은 명시 적 상태 나 고통스러운 성능 저하없이 수천 개의 스레드를 관리하는 데 사용됩니다.

요약하면 나는 귀하의 옵션 # 1에 투표 할 것입니다. 그러나 성능이 문제가 아니며 옵션 # 2 코드가 추론하기가 더 쉬운 경우에는 시도하십시오.

0

또한 bool 플래그를 사용하여 스레드를 중지해야하는지 나타낼 수 있습니다. 인터럽트와 정지 코드를 제공합니다. 그래서 두 개의 bool은 하나의 작업을위한 것이고 하나는 루프를 멈추게 할 것입니다.

다른 점은 Dispose 패턴을 사용하고 개체가 처리 될 때 스레드를 정리하는 것입니다.

0

나는 bool 플래그를 사용 하겠지만 올바르게 고정되어 있거나 한 스레드에서만 설정해야합니다. 루프가 다음과 같이 표시되어야합니다.

while (true) 
{ 
    if (shouldSleep) 
{ 
    Thread.Sleep(interval); 
    continue; 
} 

    doSomeWork(); 

if (shouldCancel) 
{ 
    CleanUpResources(); 
    break; 
} 
} 

이렇게하면 스레드를 잠자기 상태로 보낼 수 있지만 올바르게 종료 할 수 있습니다. 쓰레드를 죽이는 것은 쓰레드가 사용 된 리소스를 정리할 기회가 없기 때문에 쓰지 않는 것이 좋습니다. 그래도 적절한 수면 간격을 결정해야합니다. 스레드가 시작해야하는 대기 시간을 결정합니다.

두 번째 옵션은 다소 비쌉니다. 스레드 생성에는 일부 OS 리소스가 필요하며 시작 시간도 상당합니다. 스레드 레크리에이션이 자주 발생하지 않고 수행되는 작업의 양이 충분히 크면 합리적 일 것입니다. 루프 접근과 관련된 복잡성을 피할 수 있습니다.

1

뮤텍스 또는 세마포는 플래그의 상태를 반복적으로 검사 할 필요가 없으므로 간단한 부울 플래그보다 더 나은 옵션입니다. 단순히 뮤텍스/세마포어를 차단하고 스레드 실행을 원하면 뮤텍스/세마포어를 해제하면 스레드가 한 번 실행됩니다.

1

스레드 풀은 장기 실행 작업에는 적합하지 않습니다.스레드 풀은 오버 헤드가 많아 작업 오버 헤드가 증가하는 짧은 작업에 이상적입니다. 이것은 .NET 4 프레임 워크의 TPL (Task Paralell Library)에서도 마찬가지입니다.

이 작업을 수행하는 전용 스레드를 사용하는 것은 좋은 생각 일 수 있지만이를 관리하는 방법은 큰 문제 일 수 있습니다. 단순히 작업을 확인하는 사이에 Thread.Sleep을 수행하면 덜 효과적입니다. 이제 스레드가 아무런 이유없이 회전하기 때문입니다. 이것은 스핀 록 (kind of)이라고 불리우며 기다리고있는 리소스가 곧 잠금을 해제한다는 것을 알고있는 경우에만 효과적입니다. AutoResetEvent을 사용하는 것이 훨씬 더 좋은 방법입니다. 이렇게하면 생산자 스레드가 할 일이 있다는 신호가 있기 때문에 스레드는 깨어납니다. 이렇게해야 할 일이 없으면 스레드를 예약하기 위해 CPU 리소스를 낭비하지 않고 제작자와 소비자 간의 지연을 줄이는 이점이 있습니다.

질문에 직접 대답하려면 예. 정상적으로 스레드를 종료하려면 bool을 사용할 수 있습니다 (나는 volatile으로 표시합니다). 이것은 스레드를 중단하는 것보다 훨씬 낫습니다!

참조 :

관련 문제