옵저버 패턴을 사용하는 것보다 이벤트 폴링이 더 나은 경우는 언제입니까?


41

옵저버 패턴을 사용하는 것보다 이벤트 폴링이 더 나은 시나리오가 있습니까? 폴링 사용에 대한 두려움이 있으며 누군가 나에게 좋은 시나리오를 제공 한 경우에만 사용하기 시작합니다. 내가 생각할 수있는 것은 관찰자 패턴이 폴링보다 나은 방법입니다. 이 시나리오를 고려하십시오.

자동차 시뮬레이터를 프로그래밍하고 있습니다. 차는 물건이다. 자동차가 켜지 자마자 "vroom vroom"사운드 클립을 재생하려고합니다.

이를 두 가지 방법으로 모델링 할 수 있습니다.

폴링 : 자동차 오브젝트를 1 초마다 폴링하여 켜져 있는지 확인합니다. 켜져 있으면 사운드 클립을 재생합니다.

관찰자 패턴 : 자동차를 관찰자 패턴의 주제로 만듭니다. "on"이벤트를 켜면 모든 관찰자에게 공개하십시오. 차를 듣는 새로운 사운드 오브젝트를 작성하십시오. 사운드 클립을 재생하는 "on"콜백을 구현하십시오.

이 경우 옵저버 패턴이 이긴다고 생각합니다. 첫째, 폴링은 프로세서를 더 많이 사용합니다. 둘째, 자동차가 켜질 때 사운드 클립이 즉시 발사되지 않습니다. 폴링 기간으로 인해 최대 1 초의 간격이있을 수 있습니다.


거의 시나리오가 없다고 생각할 수 있습니다. 관찰자 패턴은 실제로 실제 세계와 실제 생활에 매핑되는 것입니다. 따라서 어떤 시나리오도 사용하지 않는 것이 정당하다고 생각하지 않습니다.
Saeed Neamati

사용자 인터페이스 이벤트 또는 일반적인 이벤트에 대해 이야기하고 있습니까?
Bryan Oakley

3
귀하의 예는 폴링 / 관측 문제를 제거하지 않습니다. 당신은 단순히 그것을 더 낮은 수준으로 전달했습니다. 자동차가 어떤 메커니즘으로 켜져 있는지 여부를 프로그램에서 확인해야합니다.
덩크

답변:


55

운전자에게 RPM 측정 값을 표시하는 등 모든 엔진주기에 대해 알림을 받고 싶다고 상상해보십시오.

관찰자 패턴 : 엔진은 "엔진주기"이벤트를 각주기의 모든 관찰자에게 공개합니다. 이벤트를 세고 RPM 표시를 업데이트하는 리스너를 작성하십시오.

폴링 : RPM 디스플레이는 엔진주기 카운터를 정기적으로 엔진에 요청하고 그에 따라 RPM 디스플레이를 업데이트합니다.

이 경우 관찰자 패턴이 느슨 할 수 있습니다. 엔진주기는 고주파수, 우선 순위가 높은 프로세스이므로 디스플레이를 업데이트하기 위해 해당 프로세스를 지연 시키거나 정지시키고 싶지 않습니다. 또한 엔진주기 이벤트로 스레드 풀을 스 래시하지 않으려 고합니다.


추신 : 나는 또한 분산 프로그래밍에서 자주 폴링 패턴을 사용합니다.

관찰자 패턴 : 프로세스 A는 "이벤트 E가 발생할 때마다 프로세스 A에 메시지를 보냅니다"라는 메시지를 프로세스 B에 보냅니다.

폴링 패턴 : 프로세스 A는 정기적으로 프로세스 B에 "마지막 폴링 이후 이벤트 E가 발생한 경우 지금 메시지를 보내십시오"라는 메시지를 정기적으로 보냅니다.

폴링 패턴은 네트워크로드를 조금 더 생성합니다. 그러나 관찰자 패턴에도 단점이 있습니다.

  • 프로세스 A가 충돌하면 원격 프로세스 실패를 안정적으로 감지 할 수없는 한 프로세스 B가 구독 취소하지 않고 프로세스 B가 영원히 알림을 보내려고 시도합니다 (쉽게 수행 할 수는 없음)
  • 이벤트 E가 매우 빈번하거나 알림에 많은 데이터가 포함 된 경우 프로세스 A는 처리 할 수있는 것보다 더 많은 이벤트 알림을받을 수 있습니다. 폴링 패턴을 사용하면 폴링을 조절할 수 있습니다.
  • 관찰자 패턴에서로드가 높으면 전체 시스템에 "리플"이 발생할 수 있습니다. 블로킹 소켓을 사용하면 이러한 리플이 양방향으로 진행될 수 있습니다.

1
좋은 지적. 때로는 성능을 위해 너무 폴링하는 것이 좋습니다.
팔콘

1
예상되는 수의 관찰자도 고려해야합니다. 많은 수의 관찰자를 예상하면 관찰 된 모든 것을 관찰하면 성능 병목 현상이 발생할 수 있습니다. 그러면 어딘가에 값을 작성하고 "관찰자"가 필요할 때 해당 값을 확인하도록하는 것이 훨씬 쉽습니다.
Marjan Venema

1
폴링을 제외하고 "원격 프로세스 실패를 안정적으로 감지 할 수없는 경우 (쉽게 수행 할 수있는 것은 아님)"... P; 따라서 최상의 설계는 "아무것도 변경되지 않았습니다"응답을 최대한 최소화하는 것입니다. +1, 정답입니다.
pdr

2
@Jojo : 그렇습니다. 그러나 디스플레이에 속하는 정책을 RPM 카운터에 넣습니다. 아마도 사용자는 때때로 매우 정확한 RPM 디스플레이를 원할 것입니다.
Zan Lynx

2
@JoJo : 각 100 번째 이벤트를 게시하는 것은 해킹입니다. 모든 가입자가 비슷한 정확도를 필요로하는 경우 이벤트 처리 시간이 엔진에 너무 오래 걸리지 않으면 이벤트 빈도가 항상 올바른 범위에있는 경우에만 잘 작동합니다. 그리고 RPM 당 하나의 모듈레이션 작업이 필요합니다 (수천 RPM으로 가정). 초당 몇 개의 폴링 작업보다 CPU에서 더 많은 작업이 수행됩니다.
nikie

7

폴링 프로세스가 폴링하는 것보다 상당히 느리게 실행되면 폴링이 더 좋습니다. 데이터베이스에 이벤트를 작성하는 경우, 모든 이벤트 생성자를 폴링하고 마지막 폴링 이후 발생한 모든 이벤트를 수집 한 다음 단일 트랜잭션으로 작성하는 것이 좋습니다. 발생한 모든 이벤트를 쓰려고 시도하면 계속 유지하지 못할 수 있으며 결국 입력 큐가 가득 찰 때 문제가 발생할 수 있습니다. 또한 지연 시간이 길거나 연결 설정 및 해제 비용이 비싼 느슨하게 연결된 분산 시스템에서 더 의미가 있습니다. 폴링 시스템을 작성하고 이해하기가 더 쉽다는 것을 알지만 대부분의 상황에서 관찰자 또는 이벤트 중심 소비자는 더 나은 성능을 제공하는 것 같습니다 (제 경험상).


7

폴링은 연결이 실패하고 서버가 작동하지 않을 때 네트워크를 통해 작업하기가 훨씬 쉽습니다 . 하루가 끝날 때 TCP 소켓에 "폴링"메시지 유지가 필요하다는 것을 기억하십시오. 그렇지 않으면 서버가 클라이언트를 가정합니다. 사라졌다.

UI 업데이트를 유지하려는 경우에도 폴링이 좋지만 기본 개체가 매우 빠르게 변경되므로 대부분의 앱에서 UI를 초당 몇 번 이상 업데이트하지 않습니다.

서버가 매우 저렴한 비용으로 "변경 없음"으로 응답 할 수 있고 너무 자주 폴링하지 않으며 1000 명의 클라이언트 폴링이없는 경우 폴링은 실제 생활에서 매우 잘 작동합니다.

그러나 " 메모리 내 "의 경우, 일반적으로 관찰자 패턴을 사용하는 것이 기본적으로 가장 작습니다.


5

설문 조사에는 몇 가지 단점이 있으므로 기본적으로 질문에 이미 언급했습니다.

그러나 옵저버 블을 옵저버에서 실제로 분리하려는 경우 더 나은 솔루션이 될 수 있습니다. 그러나 때로는 이러한 경우 관찰 할 객체에 관찰 가능한 래퍼를 사용하는 것이 좋습니다.

객체 상호 작용으로 관찰 가능 개체를 관찰 할 수없는 경우에만 폴링을 사용합니다. 콜백을 할 수없는 데이터베이스를 쿼리 할 때 자주 발생합니다. 또 다른 문제는 동시성 문제를 피하기 위해 객체를 직접 호출하지 않고 메시지를 폴링하고 처리하는 것이 더 안전한 멀티 스레딩 일 수 있습니다.


폴링이 멀티 스레딩에 더 안전한 이유를 잘 모르겠습니다. 대부분의 경우에는 그렇지 않습니다. 폴링 핸들러는 폴링 요청을 수신 할 때 폴링 된 오브젝트의 상태를 파악해야하는데, 오브젝트가 업데이트 중간에 있으면 폴링 핸들러에 안전하지 않습니다. 리스너 시나리오에서는 푸셔가 일관된 상태 인 경우에만 알림을 수신하므로 폴링 된 오브젝트에서 대부분의 동기화 문제를 피할 수 있습니다.
Lie Ryan

4

폴링이 알림에서 인계되는 좋은 예는 운영 체제 네트워킹 스택을보십시오.

네트워킹 스택이 드라이버가 인터럽트 모드 (알림)에서 폴링 모드로 전환 할 수있게 해주는 네트워킹 API 인 NAPI를 활성화 한 것은 Linux에 큰 문제였습니다.

여러 개의 기가비트 이더넷 인터페이스를 사용하면 인터럽트로 인해 종종 CPU에 과부하가 발생하여 시스템 속도가 느려질 수 있습니다. 폴링을 사용하면 네트워크 카드는 폴링 될 때까지 버퍼에서 패킷을 수집하거나 카드가 DMA를 통해 패킷을 메모리에 쓸 수도 있습니다. 그런 다음 운영 체제가 준비되면 모든 데이터에 대해 카드를 폴링하고 표준 TCP / IP 처리를 수행합니다.

폴링 모드를 사용하면 CPU가 쓸모없는 인터럽트로드없이 최대 처리 속도로 이더넷 데이터를 수집 할 수 있습니다. 인터럽트 모드는 작업량이 너무 많지 않을 때 CPU가 패킷 사이에서 유휴 상태가되도록합니다.

비밀은 한 모드에서 다른 모드로 전환 할 때입니다. 각 모드에는 장점이 있으며 적절한 장소에서 사용해야합니다.


2

나는 투표를 좋아한다! 내가합니까? 예! 내가합니까? 예! 내가합니까? 예! 아직도 그래요? 예! 지금은 어때? 예!

다른 사람들이 언급했듯이, 동일한 변경되지 않은 상태를 반복해서 되찾기 위해 폴링하는 경우 엄청나게 비효율적 일 수 있습니다. 이는 CPU 사이클을 태우고 모바일 장치에서 배터리 수명을 크게 단축시키는 방법입니다. 물론 매번 원하는만큼 빠른 속도로 새롭고 의미있는 상태를 되 찾는다면 낭비가되지 않습니다.

그러나 폴링을 좋아하는 주된 이유는 단순성과 예측 가능한 특성 때문입니다. 코드를 추적하여 언제 어디서 어떤 일이 일어날 지 쉽게 볼 수 있습니다. 이론적으로 우리가 폴링이 무시할만한 폐기물이었던 세계에 살았다면 (실제로는 멀지 만), 코드를 유지하는 것은 엄청나게 큰 일이라고 생각합니다. 이 경우에는 안되지만 성능을 무시할 수 있는지 알 수 있듯이 폴링 및 풀링의 이점입니다.

DOS 시대에 프로그래밍을 시작했을 때 내 작은 게임은 폴링을 중심으로 진행되었습니다. 키보드 인터럽트와 관련하여 간신히 이해 한 책에서 일부 어셈블리 코드를 복사하여 키보드 루프를 저장했습니다.이 시점에서 메인 루프는 항상 폴링되었습니다. 업 키가 다운입니까? 아니. 업 키가 다운입니까? 아니. 지금은 어때? 아니. 지금? 예. 좋아, 선수를 움직여

그리고 엄청나게 낭비 적이지만, 오늘날의 멀티 태스킹 및 이벤트 중심 프로그래밍에 비해 추론하기가 훨씬 쉽다는 것을 알았습니다. 나는 언제 어디서 일어날 지 정확히 알았으며 딸꾹질없이 프레임 속도를 안정적이고 예측 가능하게 유지하는 것이 더 쉬웠습니다.

그래서 그때부터 나는 항상 조건을 사용하여 스레드가 새 상태를 가져올 수있는 시점을 깨우도록 알리는 조건 변수를 사용하는 것과 같이 실제로 CPU 사이클을 태우지 않고 그 이점과 예측 가능성을 얻는 방법을 찾으려고 노력해 왔습니다. 그들의 일을하고 다시 알림을 받기 위해 다시 잠 들으십시오.

그리고 어쨌든 이벤트 큐는 관찰자 패턴보다 작업하기가 훨씬 쉽다는 것을 알았습니다. 여전히 어디로 갈지 또는 어떤 일이 일어날 지 예측하기가 쉽지는 않습니다. 최소한 이벤트 처리 제어 흐름을 시스템의 몇 가지 주요 영역으로 중앙 집중화하고 중앙 이벤트 처리 스레드 외부에서 갑자기 하나의 기능에서 완전히 먼 곳으로 튀어 나오는 대신 동일한 스레드에서 해당 이벤트를 처리합니다. 따라서 이분법이 항상 관찰자와 폴링 사이에있을 필요는 없습니다. 이벤트 대기열은 중간 정도입니다.

그러나 그렇습니다. 어쨌든 필자는 이전에 폴링 할 때 사용했던 예측 가능한 제어 흐름과 유사하게 작동하는 시스템에 대해 추론하기가 훨씬 쉽다는 것을 알았습니다. 상태 변경이 발생하지 않은 시간. 따라서 조건 변수처럼 불필요하게 CPU 사이클을 태우지 않는 방식으로 할 수 있다면 이점이 있습니다.

동종 루프

좋아, 나는 Josh Caswell내 대답에 약간의 바보가 있음을 지적한 큰 의견을 얻었다 .

"스레드가 깨어나도록 알리기 위해 조건 변수를 사용하는 것과 같음"폴링이 아닌 이벤트 기반 / 관찰자 배열처럼 들립니다

기술적으로 조건 변수 자체는 관찰자 패턴을 적용하여 스레드를 깨우거나 알리므로 "폴링"이 아마도 오도를 불러 일으킬 수 있습니다. 그러나 DOS 시절의 폴링과 비슷한 이점을 제공합니다 (제어 흐름 및 예측 가능성 측면에서). 나는 그것을 더 잘 설명하려고 노력할 것이다.

당시에 내가 찾은 것은 코드 섹션을 보거나 추적 할 수 있다는 것입니다. "이 섹션 전체는 키보드 이벤트 처리에 전념하고 있습니다.이 코드 섹션에서는 다른 일이 일어나지 않을 것입니다. 그리고 나는 앞으로 무슨 일이 일어날 지 정확히 알고 있으며, 이후에 일어날 일을 정확히 알고 있습니다 (예 : 물리와 렌더링). " 키보드 상태의 폴링은이 외부 이벤트에 대한 응답을 처리하는 한 제어 흐름의 중앙 집중화를 제공합니다. 이 외부 이벤트에 즉시 응답하지 않았습니다. 우리는 편의에 응답했습니다.

옵저버 패턴을 기반으로하는 푸시 기반 시스템을 사용하면 종종 이러한 이점을 잃게됩니다. 크기 조정 이벤트를 트리거하는 컨트롤 크기가 조정될 수 있습니다. 우리가 그것을 추적 할 때, 우리는 더 많은 이벤트를 유발하는 크기 조정에서 많은 사용자 정의 작업을 수행하는 이국적인 컨트롤 안에 있습니다. 우리는 시스템에서 어디에서 발생하는지에 관한 모든 계단식 사건을 추적하는 것에 완전히 놀랐습니다. 또한 스레드 A가 여기에서 컨트롤의 크기를 조정할 수 있지만 스레드 B도 나중에 컨트롤의 크기를 조정하기 때문에 주어진 스레드에서이 모든 것이 일관되게 발생하지 않을 수도 있습니다. 그래서 나는 항상 모든 일이 어디에서 일어날 지 예측하는 것이 얼마나 어려운지에 대해 추론하기가 매우 어렵다는 것을 알았습니다.

이벤트 큐는 스레드 스레드에서 이러한 모든 일이 발생하는 위치를 단순화하기 때문에 추론하기가 조금 더 간단합니다. 그러나 많은 다른 일들이 일어날 수 있습니다. 이벤트 큐에는 처리 할 다양한 이벤트가 포함될 수 있으며 각 이벤트는 발생하는 일련의 이벤트, 처리 된 순서 및 코드베이스의 모든 위치에서 수신 거부되는 방식에 대해 여전히 우리를 놀라게 할 수 있습니다. .

폴링에 "가장 가까운"것으로 생각하는 것은 이벤트 큐를 사용하지 않지만 매우 동종 유형의 처리를 지연시킵니다. A는 PaintSystem이 적절한 z 순서에서 내부 세포 페인트 다시 모든 것을 통해 간단한 연속 루프를 수행 지적하는 윈도우의 특정 그리드 셀을 다시 칠하기 위해 할 일이이 그림 있다는 조건 변수를 통해 경고 할 수 있습니다. 여기에 다시 페인트해야 할 셀에 상주하는 각 위젯에서 페인트 이벤트를 트리거하기 위해 간접 / 동적 디스패치 호출 레벨이 하나있을 수 있지만, 이것이 바로 하나의 간접 호출 계층입니다. 조건 변수는 관찰자 패턴을 사용하여 PaintSystem수행해야한다고 경고 하지만 그 이상을 지정하지는 않습니다.PaintSystem그 시점에서 하나의 균일하고 매우 균질 한 작업에 전념합니다. PaintSystem's코드 를 디버깅하고 추적 할 때 페인팅 이외의 다른 작업은 발생하지 않습니다.

따라서 이벤트 큐 처리에서 얻을 수있는 수많은 책임을 수행하는 이종 유형의 데이터에 대해 비균질 루프 대신 데이터에 대해 균일 한 루프를 수행하는 데이터를 대상으로 균질 루프를 수행하는 위치로 시스템을 이동시키는 것이 대부분입니다.

우리는 이런 종류의 것을 목표로하고 있습니다 :

when there's work to do:
   for each thing:
       apply a very specific and uniform operation to the thing

반대로 :

when one specific event happens:
    do something with relevant thing
in relevant thing's event:
    do some more things
in thing1's triggered by thing's event:
    do some more things
in thing2's event triggerd by thing's event:
    do some more things:
in thing3's event triggered by thing2's event:
    do some more things
in thing4's event triggered by thing1's event:
    cause a side effect which shouldn't be happening
    in this order or from this thread.

기타 등등. 그리고 작업 당 하나의 스레드 일 필요는 없습니다. 하나의 스레드는 GUI 컨트롤에 레이아웃 (크기 조정 / 위치 변경) 논리를 적용하고 다시 칠할 수 있지만 키보드 나 마우스 클릭을 처리하지 못할 수 있습니다. 따라서 이것을 이벤트 큐의 동질성을 향상시키는 것으로 볼 수 있습니다. 그러나 이벤트 큐를 사용하거나 인터리브 크기 조정 및 페인팅 기능을 사용할 필요는 없습니다. 우리는 다음과 같이 할 수 있습니다 :

in thread dedicated to layout and painting:
    when there's work to do:
         for each widget that needs resizing/reposition:
              resize/reposition thing to target size/position
              mark appropriate grid cells as needing repainting
         for each grid cell that needs repainting:
              repaint cell
         go back to sleep

따라서 위의 접근 방식은 조건 변수를 사용하여 수행 할 작업이있을 때 스레드에 알리지 만 다른 유형의 이벤트 (한 루프의 크기 조정, 다른 루프의 페인트, 둘의 혼합이 아닌 페인트)를 인터리브하지 않습니다. • 정확히 수행해야 할 작업 (스레드가 시스템 전체 ECS 상태를보고 깨어 난 스레드를 "발견")을 전달하지 않아도됩니다. 수행하는 각 루프는 본질적으로 매우 균일하므로 모든 일이 발생하는 순서를 쉽게 추론 할 수 있습니다.

이 유형의 접근 방식을 무엇으로 해야할지 모르겠습니다. 나는 다른 GUI 엔진이 이것을하는 것을 보지 못했고 그것은 내 자신의 이국적인 접근 방식입니다. 그러나 옵저버 또는 이벤트 큐를 사용하여 멀티 스레드 GUI 프레임 워크를 구현하려고 시도하기 전에 디버깅이 엄청나게 어려웠으며 자신감이 가지 않는 방식으로 해결하기에 충분하지 않은 모호한 경쟁 조건과 교착 상태가 발생했습니다. 해결책에 대해 (일부 사람들은 이것을 할 수 있지만 충분히 똑똑하지는 않습니다). 첫 번째 반복 디자인은 신호를 통해 직접 슬롯을 호출했으며 일부 슬롯은 비동기 작업을 수행하기 위해 다른 스레드를 생성했을 것입니다. 두 번째 반복은 이벤트 큐를 사용했으며 추론하기가 조금 더 쉬웠습니다. 하지만 난잡한 교착 상태와 경쟁 상황에 빠지지 않고 내 두뇌가 할 수있을만큼 쉽지는 않다. 세 번째 및 마지막 반복은 위에서 설명한 접근 방식을 사용했으며 마침내 저와 같은 바보조차 올바르게 구현 할 수있는 다중 스레드 GUI 프레임 워크를 만들 수있었습니다.

그런 다음이 유형의 최종 멀티 스레드 GUI 디자인을 사용하면 추론하기 쉬운 유형의 실수를 피하고 내가 저지른 실수를 피할 수있는 다른 것을 생각 해낼 수있었습니다. 최소한 균등 한 루프와 DOS 시절에 폴링 할 때와 비슷한 제어 흐름과 비슷한 방식 때문입니다 (실제로 폴링하지 않고 수행해야 할 작업 만 수행하더라도). 비균질 루프, 비균질 부작용, 비균질 제어 흐름을 의미하고 균일 한 데이터에서 균일하게 작동하고 격리되는 동종 루프를 향해 점점 더 많은 작업을 수행하는 것이 가능한 한 이벤트 처리 모델에서 멀어지게하는 것이 었습니다. "무엇"에 더 쉽게 집중할 수있는 방식으로 부작용을 통합


1
"스레드가 깨어나도록 알리기 위해 조건 변수를 사용 하는 것과 같음 " 폴링이 아니라 이벤트 기반 / 관찰자 배열처럼 들립니다.
Josh Caswell

나는 그 차이가 매우 미묘하다는 것을 알지만, 알림은 스레드를 깨우기 위해 "수행해야 할 작업이 있습니다"라는 형식으로되어 있습니다. 예를 들어, 관찰자 ​​패턴은 부모 컨트롤의 크기를 조정할 때 동적 크기 조정 호출이 동적 디스패치를 ​​사용하여 계층을 호출합니다. 사물은 크기 조정 이벤트 기능을 간접적으로 즉시 호출합니다. 그런 다음 즉시 다시 칠할 수 있습니다. 이벤트 큐를 사용하는 경우 부모 컨트롤의 크기를 조정하면 크기 조정 이벤트가 계층 구조로 푸시 될 수 있으며,이 시점에서 각 컨트롤의 크기 조정 기능이 지연된 방식으로 호출 될 수 있습니다.

... 그런 다음 다시 칠하기 이벤트를 푸시 할 수 있습니다. 마찬가지로 모든 것이 크기 조정이 끝나면 중앙 이벤트 처리 스레드에서 지연된 방식으로 호출됩니다. 그리고 적어도 중앙 집중화가 디버깅에 이르기까지 약간 유익하고 처리가 어디에서 발생하는지 (어떤 스레드를 포함하여) 쉽게 추론 할 수 있다는 것을 알았습니다. 이 솔루션 ...

예를 들어, LayoutSystem일반적으로 휴면 상태를 유지하지만 사용자가 컨트롤의 크기를 조정하면 조건 변수를 사용하여를 깨 웁니다 LayoutSystem. 그런 다음 LayoutSystem필요한 모든 컨트롤 의 크기를 조정하고 다시 절전 모드로 돌아갑니다. 이 과정에서 위젯이 상주하는 사각형 영역은 업데이트가 필요한 것으로 표시되며,이 시점에서 PaintSystem깨어나고 사각형 영역을 통과하여 편평한 순차적 루프로 다시 그려야하는 영역을 다시 그립니다.

따라서 조건 변수 자체는 관찰자 패턴에 따라 스레드가 깨어나도록 알립니다. 그러나 "수행해야 할 작업"이상의 정보는 전송하지 않습니다. 그리고 깨어 난 각 시스템은 균질하지 않은 작업을 처리하는 이벤트 큐 (처리 할 이벤트를 선택적으로 포함 할 수 있음)와 달리 매우 균일 한 작업을 적용하는 매우 간단한 루프로 처리하는 데 전념합니다.

-4

관찰자 후두둑에 대한 개념적인 사고 방식에 대해 더 많은 개요를 제공합니다. YouTube 채널 구독과 같은 시나리오를 생각해보십시오. 채널을 구독하는 사용자의 수가 많으며 많은 비디오로 구성된 채널에 대한 업데이트가 있으면 구독자가이 특정 채널에 변경이 있음을 알립니다. 따라서 채널이 SUBJECT 인 경우 채널에 등록 된 모든 OBSERVER를 구독, 구독 취소 및 통지 할 수 있습니다.


2
이것은 관찰자 패턴을 사용하는 것보다 이벤트 폴링이 더 나은시기를 묻는 질문을 해결하려고 시도조차하지 않습니다. 참조 답변하는 방법
모기
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.