2016-10-27 11 views
0

C++의 edsdk 개발에 멀티 헤드를 추가하려고 시도하지만 "takePictures()"에서 "takeSinglePicture()"를 실행할 때 코드가 멈추고 카메라가 하나의 그림을 가져 오지 않습니다. 이 코드를 수정하십시오.C++의 Canon EDSDK MultiThreading

일반 노트에
void CameraControl::takePictures(int n,int time) { 
    openSession(); 
    CTimer timer; 
    for (int i = 0; i < n; i++) { 
     timer.start(); 
     std::cout<<std::this_thread::get_id()<<endl; 
     takeSinglePicture(); 
     int t = timer.stop(); 
     if (t < time) std::this_thread::sleep_for(std::chrono::milliseconds(time-t)); 
     std::cout << t << std::endl; 
    } 
    closeSession(); 

} 


void CameraControl::takePicturesMT(int n,int time) { 
    std::cout << std::this_thread::get_id() << endl; 
    std::thread cameraThread([&] {CameraControl::takePictures(n,time); }); 
    cameraThread.join(); 
} 

void CameraControl::takeSinglePicture() { 
    EdsSendCommand(theCamera, kEdsCameraCommand_PressShutterButton, 1); // Half 
    EdsSendCommand(theCamera, kEdsCameraCommand_PressShutterButton, 3); // Completely 
    EdsSendCommand(theCamera, kEdsCameraCommand_PressShutterButton, 0); // Off 

} 

답변

0

, 캐논 SDK는 스레드로부터 안전하지 않습니다 및 다른 스레드에서 SDK를 함수를 호출하기 전에 Windows에서 CoInitializeEx에서 호출해야합니다 (그리고 확인되지 않은 다른 명령이 동시에 실행되어 있는지 확인) .

이 특정 경우 takePicturesMT라고하는 동일한 스레드에서 Canon SDK를 초기화했을 가능성이 가장 높습니다. Canon SDK는 초기화 스레드를 주 스레드로 사용하고 모든 명령을 실행합니다. 즉, 주 스레드에서 명령을 실행하려고하는 takeSinglePicture 명령을 호출하려고하며 주 스레드는 takePictures 스레드가 완료 될 때까지 대기합니다. -> 교착 상태입니다.

이 해결책은 스레드가 완료 될 때까지 기다리지 않고 (cameraThread.join 없음) 또는 다른 스레드에서 SDK를 초기화하는 것입니다. 두 번째 해결책은 EdsGetEvent 함수를 사용하여 자체 메시지 펌프를 구현하고 SDK 함수를 호출 할 때주의해야하기 때문에 좀 더 어렵습니다. 또한 SDK 메인 스레드가 항상 응용 프로그램 주 스레드이기 때문에 MacOS에서 작동하지 않습니다 (초기화 위치와 상관없이).