2012-11-21 1 views
0

async_connect()를 시간 초과로 구현하려고합니다.async_connect() 여러 스레드가 io_service.run()을 수행하는 동안 시간 초과.

async_connect_with_timeout(socket_type & s, 
     std::function<void(BoostAndCustomError const & error)> const & connect_handler, 
     time_type timeout); 

connect_handler(error) 조작을 완료 (시간 제한을 포함) error 나타내는 연산 결과로 불린다.

timeouts example 1.51의 코드를 사용하고 싶습니다. 가장 큰 차이점은 io_service.run()을 수행하는 여러 작업자 스레드를 사용하고 있다는 것입니다.

예제 코드가 계속 작동하려면 어떤 변화가 필요합니까?

내 문제는 다음과 같습니다 호출 할 때

  1. :

    Start() { 
        socket_.async_connect(Handleconnect); 
        dealine_.async_wait(HandleTimeout); 
    } 
    

    HandleConnect() 심지어 async_wait() (가능성이 있지만 가능) 전에 다른 스레드에서 완료 할 수 있습니다. strandStart(), HandleConnect()HandleTimeout()으로 묶어야합니까?

  2. 무엇 HandleConnect() 경우 오류없이 먼저 호출하지만, deadline_timer.cancel() 또는 deadline_timer.expires_from_now()HandleTimeout() 때문에 "가까운 미래에 호출을 위해 대기중인"실패? 예제 코드처럼 보이는 HandleTimeout() 소켓을 닫습니다. 이러한 동작 (타이머가 연결 후 행복하게 몇 가지 작업을 시작한 후에 타이머가 연결을 닫음)은 쉽게 심각한 두통을 유발할 수 있습니다.

  3. HandleTimeout()socket.close()이 먼저 호출되면 어떻게됩니까? HandlerConnect()이 이미 오류없이 "대기 중"입니까? 설명서에 "비동기 전송, 수신 또는 연결 작업은 즉시 취소되며 boost::asio::error::operation_aborted 오류로 완료됩니다." 멀티 스레딩 환경에서 "즉시"의미하는 것은 무엇입니까?

+0

'Start()'함수는 어떤 스레드에서 실행될 것으로 예상됩니까? 'io_service' 쓰레드인가, 다른 "유저"쓰레드인가요? –

+0

@IgorR.[HTTP Server 3 예제] (http://www.boost.org/doc/libs/1_51_0/doc/html/boost_asio/examples.html)의 스레드 풀을 사용하고 있습니다.보다 정확하게 말하면 : "사용자"스레드가 사용합니다. io_service.post(). – Daszek

+0

@IgorR. 'Start()'는'io_service.run()'을 호출하는'io_service' 스레드에서 호출됩니다. – Daszek

답변

1
  1. 당신이 다른 스레드에서의 병렬 실행을 방지하기 위해 원하는 경우, 각 핸들러 가닥으로 포장한다. 일부 완료 핸들러는 socket_ 또는 타이머에 액세스 할 것이므로 확실히 Start()을 줄로 묶어야합니다. 그러나 io_service-per-CPU 모델을 사용하여 즉 io_service 풀에 응용 프로그램을 구축하는 것이 훨씬 간단합니까? IMHO, 당신은 많은 덜 두통받을거야.

  2. 예, 가능합니다. 왜 두통입니까? "잘못된 시간 초과"로 인해 소켓이 닫히고 네트워크 장애로 인해 닫힌 것처럼 재 연결 (또는 무엇이든) 절차가 시작됩니다.

  3. 예, 가능하지만 올바르게 설계된 프로그램에서 문제가 발생하지 않아야합니다. HandleConnect 닫힌 소켓에서 일부 작업을 시도하면 적절한 오류가 발생합니다. 어쨌든, 데이터를 보내거나받을 때 현재 소켓/네트워크 상태를 알 수 없습니다.

+0

1)'async_connect_with_timeout()'은 몇가지 응용 프로그램에서 사용됩니다. 특정 스레딩 모델로 제한 할 수는 없습니다. 2) 나는 동의하지 않는다. 오류없이'connect_handler()'를 호출하면 나중에 "잘못된 시간 초과"가 없어 질 수 있습니다. 내 함수가'boost :: asio :: async_connect()'라고 상상해 보라. 'connect_handler() '를 호출하면 작업이 ** 완료 **되었음을 의미합니다. 3) 당신은 여기에 내 질문에 대답하지 않았다. 나는 사실을 "올바르게 설계된"이라는 구호가 아니라 싶다. 주요 질문은 "예를 들어 보겠습니다."입니다. – Daszek

+0

@Daszek 2) asio :: strand를 사용하는 경우에는 그런 문제가 없습니다. 3) * 멀티 스레딩 환경에서 "즉시"의미하는 것은 무엇입니까? * - 멀티 스레딩이 아닌 비동기 환경에서. 즉,'cancel()'(실행 대기열에 대기하지 않음)을 호출하면 콜백은 현재 처리기에서 바로 호출됩니다. – PSIAlt

+0

@PSIAlt 3) io_service.run()을 호출하는 여러 스레드 때문에 ** 멀티 스레드 **가 발생했습니다. 'close()'를 고수하십시오. 나는'cancel()'을 다루고 싶지 않다. 네가 한 말은 IgorR의 진술과 모순되는 것 같다. – Daszek