poll()
준비된 네트워크 이벤트(패킷)를 감지하고 이를 최대한 빨리 처리하는 데 사용하려는 Boost Asio를 사용하는 애플리케이션이 있습니다 .
또한 이 프로세스(단일 스레드)에서 SCHED_FIFO를 사용하여 지터를 제어하고 싶습니다(제가 해결하려는 주요 문제입니다..).
현재 제한 사항은 커널이 2.6.32(라이브 패치 없음)라는 것입니다. 여기에는 내 애플리케이션이 실행 중인 코어에서 이동할 수 없는 일부 커널 프로세스가 있고(즉, 커널이 실행되고 있지 않음) 실제 격리가 없는 것 같은 추가 문제가 있습니다. 이 문제가 다음에서 발생한다는 것을 알고 있습니다. 최신 버전의 커널 - 하지만 아직은 업그레이드할 수 없습니다. )
그래서 지금은 불친절하다면 다음과 같이 합니다.
while(some_condition)
service.poll();
프로세스는 코어를 회전시키고 SCHED_FIFO가 설정되었으므로 해당 코어에서 실행해야 하는 다른 커널 프로세스를 결코 포기하지 않으며 모든 종류의 예측할 수 없는 나쁜 일이 발생합니다. 이제 내 질문은 이 폴링 루프를 어떻게 실행하고 다른 스레드가 최소한 조금이라도 실행되도록 포기하는지 확인하는 것입니다.
두 가지 옵션이 보입니다.
- 일종의 잠
- 이벤트가 처리되지 않으면 이벤트의 어느 블록을 호출
poll()
하면 되지만run_one()
여기서 문제는 이 이벤트가 내가 원하는 패킷이 될 수 있다는 것이고 이제 다시 설레고 있습니다...
다른 방법을 놓쳤나요?
답변1
사용해본 적은 없지만 Boost::asio
언뜻 보면 사용하고 싶은데 사용 .run()
하고 싶지 않은 것 같은 느낌이 듭니다 .poll()
. Patrick이 지적했듯이 정식 poll()
시스템 호출은 수동적으로 차단할 수 있지만 asio::poll()
명시적으로는 차단할 수 없습니다(Busy-loop가 필요함).run()
하다:
run() 함수는 모든 작업이 완료되고 더 이상 핸들러를 디스패치할 필요가 없을 때까지 또는 io_service가 중지될 때까지 차단됩니다.
물론, 끊임없는 패킷 스트림을 처리하는 경우에는 문제가 해결되지 않습니다. 하지만 제 생각에는 여러분이 궁지에 몰린 것 같습니다. 시스템이 해당 코어를 정기적으로 사용해야 하고 해당 코어만 사용해야 하며 이를 포기하면 처리에 지연 시간이 발생하는 경우 이는 어려운 상황입니다.