문제

왜 "폴링이 나쁘다"는 질문을 본 적이 있습니다.하나의 스레드가 사용하는 프로세서 시간을 최소화하는 측면에서 스핀 대기(예:while 루프에서 필요한 변경 사항을 폴링하거나 커널 객체를 기다립니다(예:Windows의 커널 이벤트 객체)?

상황에 맞게 코드가 단일 코어, 하이퍼스레딩, 멀티코어 등 모든 유형의 프로세서에서 실행되어야 한다고 가정합니다.또한 대기하는 대신 폴링하는 경우 폴링 결과가 만족스러울 때까지 폴링하거나 대기하는 스레드를 계속할 수 없다고 가정합니다.마지막으로 스레드가 대기(또는 폴링)를 시작하는 시점과 조건이 충족되는 시점 사이의 시간은 잠재적으로 매우 짧은 시간에서 긴 시간까지 다양할 수 있습니다.

"대기"의 경우 OS가 더 효율적으로 "폴링"할 가능성이 높기 때문에 "대기란 다른 사람이 폴링을 수행한다는 의미일 뿐"이라는 주장을 보고 싶지 않습니다. 이는 오래된 뉴스이며 반드시 100% 정확하지는 않습니다. .

도움이 되었습니까?

해결책

OS에 이러한 유형의 동시성 프리미티브의 합리적인 구현이 있으면 커널 객체를 기다리는 것이 좋습니다.

다른 이유 중에서도,이를 통해 OS는 대기중인 물체가 적절한 상태에있을 때까지 추가 시간에 대한 해당 스레드를 예약하지 않도록 알 수 있습니다. 그렇지 않으면, 당신은 지속적으로 일정을 조정하고, 상황에 맞게 진행되고, 한 시간 동안 실행되는 스레드가 있습니다.

스레드의 프로세서 시간을 최소화하는 것에 대해 구체적으로 물었습니다.이 예에서 커널 객체의 스레드 차단은 제로 시간을 사용합니다. 폴링 스레드는 모든 종류의 시간을 사용합니다.

또한, "다른 사람이 투표하고있다"는 주장은 사실 일 필요가 없다. 커널 객체가 적절한 상태로 들어가면 커널은 해당 스레드가 해당 객체를 기다리는 순간을 볼 수 있습니다. 그런 다음 하나 이상의 실행을 예약합니다. 커널 (또는 다른 사람) 이이 경우 어떤 것을 폴링 할 필요가 없습니다.

다른 팁

기다리는 것은 "더 좋은"방법입니다. 커널 객체를 기다리는 경우 스케줄러가 작업 준비가 없다는 것을 알 수 있듯이 스레드는 CPU 시간이 부여되지 않습니다. 대기 조건이 만족되는 경우에만 CPU 시간이 주어집니다. 즉, CPU 리소스를 불필요하게 조정하지 않을 것임을 의미합니다.

아직 제기되지 않은 요점은 OS가해야 할 일이 많으면 스레드를 다른 프로세스로 차단한다는 것입니다. 모든 프로세스가 차단 프리미티브를 사용하는 경우 (예 : 커널 대기, 파일/네트워크 IO 등) 커널에 더 많은 정보를 제공하여 실행 해야하는 스레드를 선택할 수 있습니다. 따라서 같은 시간에 더 많은 작업을 수행 할 것입니다. 해당 파일이 열리기를 기다리는 동안 응용 프로그램이 유용한 작업을 수행하거나 패킷이 도착할 수 있다면 Yeilding은 귀하의 앱도 도움이 될 것입니다.

대기에는 더 많은 리소스가 포함되며 추가 컨텍스트 스위치를 의미합니다. 실제로, CLR 모니터 및 Win32와 같은 일부 동기화 프리미티브는 2 단계 잠금 프로토콜을 사용합니다. 일부 스핀 대기는 실제로 대기를하기 전에 수행됩니다.

나는 2 단계 일을하는 것이 매우 어려울 것이며 많은 시험과 연구가 필요하다고 생각합니다. 따라서 시간과 자원이 없다면 Windows 프리미티브를 고수하십시오 ... 그들은 이미 당신을 위해 연구를했습니다.

스핀-웨이팅이 의미가있는 OS 저수준 인 (인터럽트 핸들러/장치 드라이버) 내에 일반적으로 장소는 거의 없습니다. 범용 응용 프로그램은 뮤텍스/조건부 변수/세마포어와 같은 일부 동기화 프리미티브를 기다리는 것이 항상 좋습니다.

DarkSquid에 동의합니다. OS가 괜찮은 동시성 프리미티브가 있다면 여론 조사 할 필요가 없습니다. 폴링은 일반적으로 OS가없는 실시간 시스템 또는 제한된 하드웨어에서 자체적으로 제공되면 () 대기 옵션이 없을 수도 있고 ()가 필요할 수도 있기 때문에 설문 조사를해야합니다. 당신은 스케줄러의 자비에 달하는 것과는 달리 특정 상태에서 기다리기를 원합니다.

대기 (차단)는 거의 항상 최선의 선택입니다 (프로세싱 리소스를 효율적으로 사용하고 동일한 시스템에서 실행되는 다른 코드에 미치는 영향을 최소화 함). 주요 예외는 다음과 같습니다.

  1. 예상되는 폴링 기간이 작을 때 (차단 SYSCALL 비용과 크기가 유사).
  2. 대부분 내장 시스템에서 CPU가 특정 작업을 수행하기 위해 최선을 다하고 CPU 유휴 상태가 될 때 이점이 없습니다 (예 : 90 년대 후반에 내장 된 일부 소프트웨어 라우터는이 접근법을 사용했습니다.)

폴링은 일반적으로 OS 커널 내에서 차단 시스템 호출을 구현하는 데 사용되지 않습니다. 대신 이벤트 (인터럽트, 타이머, 뮤텍스에 대한 조치)가 차단 된 프로세스 또는 스레드가 실행 가능하게됩니다.

취할 수 있는 네 가지 기본 접근 방식은 다음과 같습니다.

  1. 일부 OS 대기 기본 요소를 사용하여 이벤트가 발생할 때까지 기다립니다.
  2. 이벤트가 아직 발생했는지 여부를 정의된 속도로 확인하려면 일부 OS 타이머 기본 요소를 사용하세요.
  3. 이벤트가 발생했는지 반복적으로 확인하되 OS 프리미티브를 사용하여 발생하지 않은 임의의 알 수 없는 기간에 대한 시간 조각을 생성합니다.
  4. 이벤트가 발생했는지 여부를 반복적으로 확인하고, 발생하지 않은 경우 CPU를 양보하지 마십시오.

#1이 실용적인 경우, 이벤트에 대한 응답을 지연하는 것이 유익하지 않는 한 이것이 최선의 접근 방식인 경우가 많습니다.예를 들어, 몇 초에 걸쳐 대량의 직렬 포트 데이터를 수신할 것으로 예상하고 데이터를 보낸 후 100ms 후에 처리하는 것이 즉시 처리하는 것과 같다면 후자 중 하나를 사용하여 주기적 폴링을 수행합니다. "데이터 수신" 이벤트를 설정하는 것보다 접근 방식이 더 나을 수 있습니다.

접근 방식 #3은 다소 조잡하지만 많은 경우에 좋은 접근 방식일 수 있습니다.이는 #1에 접근하는 것보다 더 많은 CPU 시간과 리소스를 낭비하는 경우가 많지만 대부분의 경우 구현이 더 간단하고 리소스 낭비는 문제가 되지 않을 만큼 작습니다.

접근 방식 #2는 #3보다 더 복잡한 경우가 많지만 전용 스레드 없이 단일 타이머로 많은 리소스를 처리할 수 있다는 장점이 있습니다.

접근법 #4는 임베디드 시스템에서 때때로 필요하지만 하드웨어를 직접 폴링하지 않는 한 일반적으로 매우 좋지 않으며 문제의 이벤트가 발생할 때까지 수행할 유용한 작업이 없습니다.대부분의 경우 대기 중인 스레드가 CPU를 생성할 때까지 대기 중인 조건이 발생하는 것은 불가능합니다.접근 방식 #3에서와 같이 CPU를 양보하면 실제로 대기 중인 스레드가 이벤트를 독차지하는 것보다 더 빨리 이벤트를 볼 수 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top