특정 목적의 함수 수행에 걸리는 시간이 오래걸리는 경우 백그라운드에서 돌아가게 냅두고 지정시간이 지나면 타임아웃 처리하여 함수 콜 다음행으로 진행시키는 코드입니다.
예문으로 OpenCV의 BlobDetection 수행 상황을 가정해봅니다.
#include <opencv2/opencv.hpp>
#include <opencv2/features2d.hpp>
#include <thread>
#include <future>
#include <iostream>
using namespace cv;
using namespace std;
// Blob Detection 함수
vector<KeyPoint> detectBlobs(const Mat& image, Ptr<SimpleBlobDetector> detector)
{
vector<KeyPoint> keypoints;
detector->detect(image, keypoints);
return keypoints;
}
int main()
{
// 이미지 로드
Mat img = imread("example.jpg", IMREAD_GRAYSCALE);
if (img.empty())
{
cout << "이미지를 불러올 수 없습니다." << endl;
return -1;
}
// SimpleBlobDetector 설정
Ptr<SimpleBlobDetector> detector = SimpleBlobDetector::create();
// 비동기 호출
auto future = async(launch::async, detectBlobs, img, detector);
// 타임아웃 설정 (예: 2초)
chrono::seconds timeout(2);
// 결과 대기
if (future.wait_for(timeout) == future_status::ready)
{
// 완료된 경우 결과 가져오기
vector<KeyPoint> keypoints = future.get();
cout << "Blob Detected: " << keypoints.size() << " 개" << endl;
// 키포인트 그리기 및 출력
Mat output;
drawKeypoints(img, keypoints, output, Scalar(0, 0, 255),
DrawMatchesFlags::DRAW_RICH_KEYPOINTS);
imshow("Blob Detection", output);
waitKey(0);
}
else
{
// 타임아웃 발생
cout << "Blob Detection Time Out!" << endl;
}
return 0;
}
BlobDetection에서 2초 이상의 시간이 걸리는 경우, 이미 호출된 detectBlobs()함수는 끝날때까지 수행하지만, main() 함수에서는 2초 Timeout으로 "Blob Detection TIme Out !" 이라는 메세지를 출력할 것입니다.
초 단위가 아닌, 밀리초 단위로 Timeout을 걸고 싶을 때는 chrono::seconds 대신 chrono::milliseconds를 사용하면 됩니다.
주의하실 점은, 이미 펑션콜 된 detectBlobs는 제 기능을 계속 수행중이며, detectBlobs의 return이 오기 전까지는 main() 함수 역시 return을 하지 못하고 대기하게 됩니다. 즉, 비동기 호출 함수 내부에서 무한루프가 걸리는 경우를 조심해야 한다는말씀입니다.
이점을 주의하신다면 다양한 경우의 필요에 의한 펑션콜에 Timeout 속성을 부여할 수 있습니다.