Win7 x64에서는이 기능과 동일한 기능을 구현해야합니다.Java의 LockSupport.parkNanos()와 동일한 Windows C++
처음에는 SwitchToThread()
을 사용했지만 극한 상황에서 교착 상태가 발생하기 때문에이 방법은 작동하지 않습니다. 내가 찾을 수있는 유일한 대안은 Sleep()
입니다. 아직 밀리 초 해상도에서만 작동하므로 성능 희생자가 될 가능성이 높습니다. 그래도 여전히 LockSupport.parkNanos()
과 같은 작업을 수행하는지 확신 할 수 없습니다.
의심 스럽지만 나노초 간격으로 스레드를 스케줄링 할 수있는 자바의 기능을 발견 했으니까요. 그러나 이것이이 문제를 해결하는지 확신 할 수는 없지만 자바 기능이 JVM의 개입을 필요로하는 것처럼 필연적으로 지연 될 수 있습니다. parkNanos
에 대한 소스 코드가 없습니다. 원시 Sun 라이브러리에서 구현됩니다.
class LockSupport
{
public:
static void ParkNanos(unsigned __int64 aNanos)
{
ULONGLONG start;
ULONGLONG end;
::QueryUnbiasedInterruptTime(&start);
do
{
// My issue with this is that nothing is actually 'Parked'.
::SwitchToThread();
::QueryUnbiasedInterruptTime(&end);
}
while ((end - start) < aNanos);
}
};
호출 코드는 다음과 같습니다
void SomeClass::SomeFunction()
{
while (someCond)
{
LockSupport.parkNanos(1L);
}
}
FWIW, 나는 C에 LMAX의 스럽 패턴을 포팅하고 ++. 교착 상태는 한 스레드가 SingleThreadedClaimStrategy::WaitForFreeSlotAt()
이고 다른 스레드가 BlockingWaitStrategy::WaitFor
(시간 초과 없음) 일 때 발생합니다. 교착 상태는 RingBuffer 크기가 1, 2, 4, 8 등일 때 더욱 분명합니다.
스레드는 보통 CreateThread
수단으로 생성됩니다.
편집 : 제가 이것을 작성했을 때 꽤 늦었습니다. 그래서 여기에 더 많은 정보가 있습니다. RingBuffer에는 __int64
이 저장됩니다. 하나의 Producer 스레드와 하나의 Consumer 스레드가 있습니다. 또한 Consumer 스레드는 마지막으로 소비 한 이벤트의 시퀀스 번호에 대해 매 초 Consumer를 폴링하는 Timer 스레드를 생성합니다. 소비자가 아무런 진전을 보이지 않고 생산자도 끝나지 않은 시점이 있습니다. 프로듀서는 카운터를 게시하는 데 수억 번 반복됩니다. 따라서 내 출력은 다음과 같습니다.
898
97
131
Timer: no progress
Timer: no progress
...
속도는 모두 최적화 된 릴리스 모드에서만 재생됩니다.
당신은':: SwitchToThread()'로 교착 상태에 빠졌다고합니다. 진실한가 거짓인가? – Managu
@Managu 정상 실행 중에는 두 가지 모두를 반환 할 수 있습니다. 그러나 귀하의 의견은 나에게 거짓을 반환하는 동안이 기능을 회전시키는 아이디어를주었습니다. – James
BlockingWaitStrategy에서 사용하는 ReentrantLock 및 Condition은 어떻게 구현하고 있습니까? 잠금 구현이 재진입 성입니까? 조건 변수가 원자 적으로 해당 잠금을 획득하거나 해제합니까? – Managu