C ++ : 임의의 기능 호출을위한 타임 아웃을 구현하는 방법은 무엇입니까?

StackOverflow https://stackoverflow.com/questions/879896

  •  22-08-2019
  •  | 
  •  

문제

불행히도 주어진 시간 내에 종료되지 않는 라이브러리 기능을 호출해야합니다. 함수를 호출하는 방법이 있지만 내면이 끝나지 않으면 중단합니다. n 몇 초?

기능을 수정할 수 없으므로 중단 조건을 직접 넣을 수 없습니다. 나는해야한다 외부에서 기능에 시간 초과를 추가하십시오.

(부스트) 스레드로 시작할 수있는 솔루션 일 수 있습니까? 그런 다음 특정 시간 후에 종료 될 수 있습니까? 그런 일이 작동할까요? 나는 실제로 기능이 있다고 믿는다 ~ 아니다 스레드-안전하지만, 내가 그것을 단일 스레드, 맞습니까? 다른 (더 나은) 솔루션이 있습니까?

도움이 되었습니까?

해결책

당신은 스폰 할 수 있습니다 boost::thread API를 호출하려면 :

boost::thread api_caller(::api_function, arg1, arg2);
if (api_caller.timed_join(boost::posix_time::milliseconds(500)))
{
    // API call returned within 500ms
}
else
{
    // API call timed out
}

그러나 부스트는 작업자 스레드를 죽일 수 없습니다. 이 예에서는 단지 고아입니다.

API 호출이 수행하는 일에주의를 기울여야합니다. 획득 한 리소스를 공개 할 수 없기 때문입니다.

다른 팁

이것을 달성하는 유일한 안전한 방법은 별도의 것을 스폰하는 것입니다. 모래 상자 라이브러리를 호출하는 프로세스를 응용 프로그램의 프록시로합니다. 응용 프로그램과 프록시 사이에 일부 유형의 IPC를 구현해야합니다. IPC 답변을 읽는 데있어 타임 아웃을 구현하는 것은 상당히 사소합니다. 시간 초과로 인해 읽기가 실패하면 응용 프로그램의 건강을 위험에 빠뜨리지 않고 프록시를 안전하게 종료 할 수 있습니다.

당신이 말하는 것은 일반적으로 "워치 독"시스템이라고합니다. 워치 독은 일반적으로 다른 모든 스레드의 상태를 확인하는 두 번째 스레드입니다. 워치 독은 일반적으로 주기적으로 실행하도록 설정됩니다. 다른 스레드로부터 응답이 접수되지 않은 경우, 워치 독은 사용자에게 알리거나 안전하게 할 수있는 경우 (응용 프로그램에 따라 다름) 불쾌한 스레드를 죽일 수 있습니다.

스레드의 문제점은 스레드 종료 후 자유롭지 않을 일부 리소스가 있다는 것입니다. 릴리스 해야하는 리소스를 획득하지 않으면 스레드와 함께 가십시오.

문제는 프로세스 내 솔루션을 사용하는 것입니다 기능으로부터 지원하지 않고 당신은 잠재적으로 유효하지 않은 상태로 끝납니다.

예 : 메모리 할당이 발생하는 동안 스레드를 종료하면 프로세스 힙이 손상 될 수 있습니다.

따라서 전화를 종료 할 수도 있지만 프로세스를 종료해야합니다. 많은 경우에, 파괴적인 부작용에 대한 기회는 적지 만, 나는 그것에 대한 내 계산을 내기하지 않을 것입니다.

Ben Straub가 제안한 것처럼 스레드를 고아로 삼을 수 있습니다. 최우선 순위를 높이고 무한대로 실행하도록하십시오. 물론 제한된 솔루션 일뿐입니다. 스레드가 Ressources (아마도)를 소비하면 시스템을 늦추고 프로세스 당 스레드에 제한이 있습니다 (일반적으로 스레드 스택의 주소 공간으로 인해).

일반적으로 외부 프로세스 솔루션을 선호합니다. 간단한 패턴은 이것입니다.
입력 데이터를 파일에 작성하고 파일로 인수로 외부 프로세스를 시작합니다. 외부 프로세스는 모니터링 할 수있는 디스크 파일에 진행 (있는 경우)을 기록하며 프로세스가 시작된 위치에서 재개 할 수도 있습니다. 결과는 디스크에 기록되며 부모 프로세스는이를 읽을 수 있습니다.

프로세스를 종료 할 때 여전히 외부 ressources (파일과 같은)에 대한 액세스를 동기화하고 버려진 뮤직 스, 반 작성 파일 등을 처리하는 방법을 다루어야하지만 일반적으로 강력한 솔루션으로가는 방법입니다.

당신이 필요로하는 것은 스레드와 a입니다 미래의 대상 함수 호출에서 결과를 유지할 수 있습니다.

Boost를 사용하는 예는 참조하십시오 여기.

시간 초과 후 미래를 확인하고 설정되지 않은 경우 그에 따라 행동하십시오.

고아 프로세스를 사용하여 시작하여 실행 시간에 시간을 보내십시오. 시간이 부족한 경우 OS를 호출하여 죽입니다.

인종 사기를 피하는 방법. 이 패턴에 대해 :

  • Args에 저장할 파일을 만듭니다 (물론 모든 것이 vals로 전달됩니다). 고아 프로세스는이 파일의 데이터 만 읽을 수 있습니다.

  • 고아는 입력 데이터를 처리하고 결과 값이있는 출력 파일을 생성하고 닫습니다.

  • 모든 것이 완료 될 때만 Orphan은 입력 파일을 삭제합니다. 사실 작업이 수행 된 마스터 프로세스를 신호합니다.

마스터가 먼저 입력 파일의 부재를 알아 차리고, 입력을 삭제하기 전에 닫히고 OS 호출 스택이 순차적이기 때문에 반드시 완료된 출력 파일을 읽습니다.

"불행히도 주어진 시간 내에 종료되지 않는 라이브러리 기능을 호출해야합니다. 불행히도 기능을 호출 할 수있는 방법이 있지만 N 초 안에 종료되지 않으면 중단해야합니까?"

짧은 대답은 아니오입니다. 일반적으로 문제가 있습니다 ... 전화 자체는 언젠가는 (자체 시간 초과 구현) 종료되어야하지만, 전화 차단은 일반적으로 문제입니다 (예 : GethostbyName ()).

따라서 필요할 때 스레드에서 코드를 실행하려고 시도 할 때마다 코드 자체가 오류를 감지하고 처리해야합니다. 메인 (또는 aother) 스레드가 무슨 일이 있었는지 알 수 있도록 메시지 및/또는 설정 상태를 보낼 수 있습니다.

개인 취향, 고도로 가용 시스템에서 나는 특정 시간 초과, 비 블로킹 기능을 호출하며 정확한 종료 조건이있는 스레드가 종종 회전하는 것을 좋아합니다 (바쁜 잠금은 없음). 글로벌 또는 스레드 별 '완료'변수는 깨끗한 출구에 대한 트릭을 수행합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top