0

I try to add multitheading to edsdk development in c++.but the code get stuck when executing "takeSinglePicture()" in "takePictures()" ,and the camera wont even take a single picture.how to fix this.the code is here.

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

}

1 Answers1

0

On a general note, the Canon SDK is not thread safe and before calling an SDK function on a different thread you need to call CoInitializeEx on Windows (and make sure not other command is executed at the same time).

In this specific case the problem is most likely that you initialized the Canon SDK on the same thread you call takePicturesMT. The Canon SDK uses the initialize thread as main thread and executes all commands there. This means that you try to call the takeSinglePicture command, which tries to execute the command on the main thread and the main thread waits for the takePictures thread to finish -> deadlock.

The solution to this would be to either not wait for the thread to finish (no cameraThread.join) or to initialize the SDK on a different thread. The second solution is quite a bit more difficult because then you need to implement your own message pump (with the EdsGetEvent function) and be careful from where you call SDK functions. It also doesn't work on macOS because there the SDK main thread is always the applications main thread (no matter from where you initialize).

Johannes Bildstein
  • 1,069
  • 2
  • 8
  • 20