가짜 웨이크 업 설명은 수정 할 가치가없는 버그처럼 들립니다. 맞습니까?


30

Spurious Wakeups 에 관한 Wikipedia 기사에 따르면

"스레드가 조건 변수를 신호하지 않더라도 스레드는 대기 상태에서 해제 될 수 있습니다."

이 '기능'에 대해 알고 있었지만 같은 기사에서 실제로 그 원인을 알 수 없었습니다.

"의심스러운 깨우기는 이상하게 들릴지 모르지만 일부 다중 프로세서 시스템에서는 조건 깨우기를 완전히 예측할 수있게하면 모든 조건 변수 작업이 상당히 느려질 수 있습니다."

고칠 가치가없는 버그 인 것 같습니까?


1
관련 : "pthread_cond_wait에 왜 가짜 웨이크 업이 발생합니까?", stackoverflow.com/questions/8594591/…
— Florian Castellane

답변:


39

스퓨리어스 웨이크 업의 TL; DR 가정 ( "계약")은 스레드 쉴더의 현실적으로 강력한 구현을 가능하게하기위한 합리적인 아키텍처 결정입니다.

여기서 "성능 고려 사항"은 관련이 없으며, 이는 권위있는 참고 문헌에 언급되어 널리 퍼져있는 오해입니다. (권한있는 참조는 오류가있을 수 있습니다. ' 갈릴레오 갈릴레이 에게 물어보십시오. ) 위키 백과 문서는 완벽하게 게시 된 참조를 인용의 공식적인 가이드 라인을 일치하기 때문에 방금 인용 노트에 대한 참조를 유지합니다.

이 답변 에는 가짜 웨이크 업 개념을 도입하는 훨씬 더 설득력있는 이유 가 바로이 기사의 (이전 버전)에 제공된 추가 세부 정보를 기반으로합니다.

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

pthread_cond_wait()Linux 의 기능은 futex시스템 호출을 사용하여 구현됩니다 . EINTR프로세스가 신호를 수신하면 Linux의 각 차단 시스템 호출이 갑자기 리턴 됩니다. ... 시스템 호출 pthread_cond_wait()이 아닌 시간에 실제 깨우기를 놓칠 수 있기 때문에 대기를 다시 시작할 수 없습니다 futex...

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

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

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


실의 관점에서 이것은 다소 Postel의 법칙 (일명 견고성 원칙 ) 과 비슷합니다 .

당신이하는 일에 보수적이며, 다른 사람들로부터 받아들이는 것에 자유 롭다

가짜 웨이크 업을 가정하면 스레드가 수행하는 작업 에서 다른 스레드를 알릴 때 조건을 설정 하고 허용되는 자유를 강제 합니다 . 대기에서 돌아올 때의 상태를 확인하고 아직 없으면 대기를 반복합니다.


10
Ugh ... Postel의 법칙 ... HTML 및 모든 종류의 웹 기술에 너무 많은 문제가 발생하는 이유 (예 : 잘못된 태그 중첩의 HTML 승인). 좋은 답변입니다.
— Thomas Eding

3
Postel의 법칙은 함수가 잘못된 출력을 반환하더라도 앱이 여전히 작동하는 것처럼 보이기 때문에 많은 버그가 몇 년 동안 잡히지 않는 이유입니다. 최고의 발명품.
— Pacerier 2016 년

2
@Pacerier : 잘못된 출력을 반환하는 함수가 Postel의 법칙 (보수적 부분)을 따르지 않습니다.
— YvesgereY

@Pacerier : OTOH, 다른 구성 요소를 엄격하게 요구하여 버그를 조기에 발견 할 수있는 것은 'Fail Fast'원칙과 'Contract Based'설계 측면에서 잘못된 위치입니다.
— YvesgereY

1

어쨌든 발신자 코드는 경쟁 조건을 처리하기 위해 동일한 처리 (조건 확인)를 사용해야하기 때문에 해결할 가치가 없습니다.

두 가지 문제에 대한 한 가지 치료법은 다음과 같습니다.

스퓨리어스 웨이크 업 : 대기 스레드가 조건이 설정되기 전에 스케줄됩니다.
강제 오버 슬립 : 조건이 다시 위조 된 후 대기 스레드가 스케줄됩니다.

후자가 발생할 수 있기 때문에 일부는 계약에서 가짜 웨이크 업을 도입하기까지했습니다.

  • 술어 루프를 요구하여 모범 사례를 시행합니다.
  • 스케줄러 구현에 대한 자유를 제공합니다 (@gnat이 지적한 응급 복구 옵션 포함).

SO 참조


나는 이것을 +1하고 싶지만, 누군가가 강제 오버 슬립을 해결하기 위해 술어 루프를 추가하기 위해 호출자가 의도적으로 가짜 웨이크 업을 도입했다는 아이디어를 위해. 나는 상상할 수없는 것을 발견했다.
— ruakh

'의견은 술어 루프를 요구하여 정확하고 견고한 코드를 강제하는 것이 었습니다.' 제공된 링크를 참조하십시오.
— YvesgereY
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.