多线程
本教程演示了如何从多个线程安全地操作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();
}
我们建议在一个线程中连接到所有相机,然后生成控制相机的新线程(从多个线程同时"使用"同一相机是线程安全的)