2012-11-26 2 views
0

내 앱 (C++, Windows)이 외부 장치와 통신 중입니다. 특정 시간이 지난 후 장치가 응답하지 않으면 상태 변수를 재설정하려고합니다.C++을 사용하여 시간 초과 후 변수 재설정

내 초기 접근 방식은 내가 설문 조사() 대신에 실행() (here 본)을 선택하는 이유

auto timer = boost::asio::deadline_timer(io_svc); 

timer.expires_from_now(boost::posix_time::seconds(10)); 
timer.async_wait(boost::bind(&Class::CurrRequestTimeout, this, boost::asio::placeholders::error)); 

io_svc.poll(); 

및 타임 아웃 기능이

void Class::CurrRequestTimeout(const boost::system::error_code & ec) 
{ 
    if (ec) 
    { 
     // this timeout was canceled 
     return; 
    } 
    ResetStatusVariable(); 
} 

이 비 차단해야한다, 그건 것 . 그러나 poll()을 사용하면 timeout 메소드가 호출되지 않습니다. run()을 사용하면 잘 작동하지만 실행을 차단합니다.

+0

타임 아웃 메서드를 호출해야하는 코드는 어디에 있습니까? 붙여 넣지 않았다면 해주세요. 그러한 코드가 없다면 문제가 있습니다. –

+0

async_wait()는 제한 시간이 만료되거나 취소 된 후에 timeout 메서드를 호출해야합니다. 적어도 그것이 http://www.boost.org/doc/libs/1_48_0/doc/html/boost_asio/reference/basic_deadline_timer/async_wait.html – Simon

+1

에 대한 나의 이해입니다. 이것이 맞다면 어떻게 될까요? 다른 스레드는 없습니다. 적어도 우리에게 보여준 스레드는 아닙니다. 그리고'async_wait'는 아직 시간이 없기 때문에 그 함수를 호출 할 수 없습니다. 그러면 어떻게 그렇게 될 수 있겠습니까? –

답변

2

poll 함수는 그 순간에 실행할 준비가 된 핸들러 만 실행합니다. 타이머가 아직 시간 초과되지 않았으므로 이제 해당 처리기를 실행할 수 없습니다. 그리고 당신은 그것을 막지 말 것을 요청했습니다. 그래서 당신은 무엇을 기대합니까?

코드가 스레드 안전 인 경우 run에 차단할 수있는 다른 스레드를 만드십시오. 그렇지 않다면이 스레드는 돌아와서 처리기에게 실행할 기회를주기 위해 나중에 poll을 호출해야합니다.

주의 사항 : 하나 이상의 run 스레드를 만들려면 기다려야 할 이벤트가 항상 하나 이상 있어야합니다. 그렇지 않으면 스레드가 처리기를 기다릴 수 없습니다. boost::asio::io_service::work은이 목적을 위해서 존재합니다. this question을 참조하십시오.

+0

나는 비동기적인 예제에서 나의 해결책을 도출하려했다 : http://www.boost.org/doc/libs/1_48_0/ docync_wait() async_wait()는 핸들러를 – Simon

+1

번으로 실행한다고 생각합니다. async_wait() 함수는 즉시 반환하고 핸들러가 isn ' 아직 실행할 준비가되지 않았다. 어떤 코드가 실행 되더라도 핸들러는 10 초 후에 실행되는 코드 여야합니다. –

+0

내 코드에서 run()을 별도의 스레드 (이미 존재 함)에 넣는 해결책을 찾았습니다. 귀하의 설명에 다시 한 번 감사드립니다. – Simon

0

시간 초과 이전에 poll을 호출하면 io_service 폴링이 아무런 조치없이 반환되기 때문에 (아직) 수행 할 작업이 없습니다. 타임 아웃이나 외부 장치와의 통신을 기다리는 동안 무엇을하고 싶습니까? 당신은 시간 제한 플래그의 외부 장치 통신, 폴링 io_service 기다리고 확인, 루프를 실행할 수 있습니다 :

while (!checkForExternalDevicesCommunication()) 
{ 
    io_svc.poll(); 
    if (statusVariableHasTimeout()) 
    throw CommunicationTimeoutException(); 

    doSomethingInTheMeanTime(); 
    std::this_thread::sleep(some_time); 
} 

또는 비동기 방식으로 Boost.Asio 스타일을 외부 기기와의 통신을 구현하고하자 동일한 io_service에서 실행됩니다.

+0

deadline_timer가 이미 나를 위해 스레드를 만들 것이라고 가정하고있었습니다 (위의 내 질문에 대한 내 의견 참조). 설명 주셔서 감사합니다. – Simon

+0

이것은 데드 라인 타이머의 로직을 완벽하게 무효화합니다. –

+0

@DavidSchwartz가 자세히 설명합니까? –

관련 문제