多线程

本教程演示了如何从多个线程安全地操作Zivid相机。在下面的示例中,我们在一个线程中连续轮询相机的状态,同时我们从其它线程对同一相机的进行队列捕获。

备注

从SDK 2.9开始,Zivid SDK支持同时从多个线程操作同一个相机。

首先,我们创建不同的设置来区分不同的捕获。我们使用不同的曝光时间,以便通过观察投影图案轻松注意到捕获之间的差异。

std::cout << " Creating different settings to distinguish between different captures" << std::endl;
const auto settings0 =
    Zivid::Settings{ Zivid::Settings::Engine::phase,
                     Zivid::Settings::Acquisitions{ Zivid::Settings::Acquisition{
                         Zivid::Settings::Acquisition::Aperture{ 5.66 },
                         Zivid::Settings::Acquisition::Gain{ 1.0 },
                         Zivid::Settings::Acquisition::ExposureTime{ std::chrono::microseconds{ 10000 } } } } };
const auto settings1 = Zivid::Settings{ Zivid::Settings::Acquisitions{ settings0.acquisitions().at(0).copyWith(
    Zivid::Settings::Acquisition::ExposureTime{ std::chrono::microseconds{ 30000 } }) } };
const auto settings2 = Zivid::Settings{ Zivid::Settings::Acquisitions{ settings0.acquisitions().at(0).copyWith(
    Zivid::Settings::Acquisition::ExposureTime{ std::chrono::microseconds{ 90000 } }) } };

然后,我们运行一个线程,不断检查相机的状态。

pollingThreads.emplace_back(std::async(std::launch::async, [&]() {
    while(!stop)
    {
        const auto state = camera.state();
        std::cout << "Camera: " << camera.info().serialNumber() << std::endl;
        std::cout << state << std::endl;
        std::this_thread::sleep_for(std::chrono::milliseconds(5000));
    }
}));

最后,我们通过另外的三个线程对三个捕获进行排队,每个线程使用了不同的设置。

const auto frame0 = std::async(std::launch::async, [&]() { return camera.capture(settings0); });
const auto frame1 = std::async(std::launch::async, [&]() { return camera.capture(settings1); });
const auto frame2 = std::async(std::launch::async, [&]() { return camera.capture(settings2); });

如您所见,从不同线程操作同一个相机非常简单。但是,某些特定API或情况下存在一些限制,需要避免这些限制以保证程序的安全行为:

您不得在调用以下任何API的同时操作相机:

  • Zivid::Application::cameras()

  • Zivid::Camera::connect()

  • Zivid::Firmware::update()

这同样适用于从多个线程同时调用上述API的任意组合。

使用多个Zivid相机时,重要的是列出相机并通过SDK按顺序连接到这些相机。

std::cout << "Finding cameras" << std::endl;
auto cameras = zivid.cameras();
std::cout << "Number of cameras found: " << cameras.size() << std::endl;

// It is important to connect to cameras sequentially
for(auto &camera : cameras)
{
    std::cout << "Connecting to camera: " << camera.info().serialNumber().value() << std::endl;
    camera.connect();
}

我们建议在一个线程中连接到所有相机,然后生成控制相机的新线程(从多个线程同时"使用"同一相机是线程安全的)