Programming

Java에서 가짜 웨이크 업이 실제로 발생합니까?

procodes 2020. 5. 8. 21:30
반응형

Java에서 가짜 웨이크 업이 실제로 발생합니까?


다양한 잠금 관련 질문을보고 (거의) 항상 '스퓨리어스 웨이크 때문에 루프를 찾는다'라는 용어가 궁금합니다 .1 누군가가 그런 종류의 웨이크 업을 경험 한 적이 있습니까 (예 : 괜찮은 하드웨어 / 소프트웨어 환경 가정)?

나는 '스퓨리어스 (spurious)'라는 용어가 명백한 이유를 의미하지 않지만 그러한 종류의 사건에 대한 이유는 무엇입니까?

( 1 참고 : 반복 연습에 의문의 여지가 없습니다.)

편집 : 도우미 질문 (코드 샘플을 좋아하는 사람들을위한) :

다음 프로그램이 있고 실행하면

public class Spurious {
    public static void main(String[] args) {
        Lock lock = new ReentrantLock();
        Condition cond = lock.newCondition();
        lock.lock();
        try {
            try {
                cond.await();
                System.out.println("Spurious wakeup!");
            } catch (InterruptedException ex) {
                System.out.println("Just a regular interrupt.");
            }
        } finally {
            lock.unlock();
        }
    }
}

await임의의 이벤트를 영원히 기다리지 않고 이를 가짜 로 깨우려면 어떻게해야 합니까?


가짜 웨이크 업에 관한 Wikipedia 기사 에는 다음과 같은 내용이 있습니다.

pthread_cond_wait()Linux 기능은 futex시스템 호출을 사용하여 구현됩니다 . EINTR프로세스가 신호를 수신하면 Linux의 각 차단 시스템 호출이 갑자기 리턴 됩니다. ... 시스템 호출 pthread_cond_wait()이 아닌 시간에 실제 깨우기를 놓칠 수 있으므로 대기를 다시 시작할 수 없습니다 futex. 이 경쟁 조건은 호출자가 불변 값을 확인해야만 피할 수 있습니다. 따라서 POSIX 신호는 가짜 웨이크 업을 생성합니다.

요약 : 리눅스 프로세스가 신호를 받으면 대기중인 스레드는 각각 멋진 핫 스퓨리어스 웨이크 업을 즐깁니다 .

나는 그것을 산다. 일반적으로 모호한 "성능을위한"이유보다 삼키기 쉬운 피임약입니다.


이 동작을 보여주는 생산 시스템이 있습니다. 스레드는 큐에 메시지가 있다는 신호를 기다립니다. 사용량이 많은 기간에는 최대 20 %의 웨이크 업이 의심됩니다 (즉, 웨이크 업시 큐에 아무것도 없음). 이 스레드는 메시지의 유일한 소비자입니다. Linux SLES-10 8 프로세서 박스에서 실행되며 GCC 4.1.2로 빌드됩니다. 시스템이 메시지를 충분히 빨리 읽지 못하면 문제가 있기 때문에 메시지는 외부 소스에서 가져오고 비동기 적으로 처리됩니다.


제목의 질문에 대답하려면- 그렇습니다! 그것은 happen.Though는 않습니다 위키 문서는 내가 통해 들어와 다음 있는지 의사를 깨우는에 대해 동일한에 대한 좋은 설명을 좋은 거래를 언급 -

그냥 생각해보십시오 ... 모든 코드와 마찬가지로 스레드 스케줄러는 기본 하드웨어 / 소프트웨어에서 비정상적인 문제로 인해 일시적인 정전이 발생할 수 있습니다. 물론, 가능한 한 드물게 발생하도록주의를 기울여야하지만, 100 % 강력한 소프트웨어와 같은 것은 없기 때문에 스케줄러가이를 감지 할 경우 이러한 상황이 발생할 수 있다고 가정하고 적절한 복구를 수행하는 것이 합리적입니다 (예 : 누락 된 하트 비트를 관찰하여).

이제 스케줄러가 정전 중에 대기 스레드에 알리는 일부 신호가 누락 될 수 있다는 점을 고려하여 어떻게 스케줄러를 복구 할 수 있습니까? 스케줄러가 아무 것도하지 않으면 언급 된 "불운"스레드가 중단되어 영원히 대기합니다.이를 피하기 위해 스케줄러는 단순히 모든 대기 스레드에 신호를 보냅니다.

따라서 대기 스레드에 이유없이 통지 할 수있는 "계약"을 설정해야합니다. 정확히 말하면, 스케줄러 정전이 발생하는 이유가 있지만 스레드가 스케줄러 내부 구현 세부 사항에 대해 알 수 없도록 설계되었으므로이 이유는 "스퓨리어스"로 표시하는 것이 좋습니다.

나는 출처 에서이 답변을 읽었 으며 충분히 합리적이라고 생각했습니다. 또한 읽으십시오

자바에서 가짜 웨이크 업과이를 피하는 방법 .

추신 : 위의 링크는 가짜 모닝콜에 대한 추가 정보가있는 개인 블로그로 연결됩니다.


카메론 퍼디 (Cameron Purdy)가짜 모닝콜 문제에 부딪 치는 것에 대해 블로그 게시물을 작성했다 . 네, 그래요

Java가 배포되는 일부 플랫폼의 제한 때문에 사양에 있다고 생각합니다. 내가 틀렸을 수도 있지만!


이것을 추가하십시오. 그렇습니다. 24 코어 시스템 (JDK 6)에서 멀티 스레딩 문제의 원인을 검색하는 데 3 일을 보냈습니다. 10 건 중 4 건은 아무런 패턴없이 경험했습니다. 이것은 2 코어 또는 8 코어에서 발생하지 않았습니다.

일부 온라인 자료를 연구했으며 이는 Java 문제가 아니라 일반적이지만 드물지만 예상되는 동작입니다.


https://stackoverflow.com/a/1461956/14731 에는 기본 운영 체제가 트리거하지 않는 경우에도 가짜 웨이크 업으로부터 보호해야하는 이유에 대한 훌륭한 설명이 들어 있습니다. 이 설명은 Java를 포함한 여러 프로그래밍 언어에 적용됩니다.

참고URL : https://stackoverflow.com/questions/1050592/do-spurious-wakeups-in-java-actually-happen

반응형