Is Opening multiple cameras together thread safe?

Hello all,
Just a question about the Cvb::DeviceFactory::Open() function. I have a area scan and a line scan camera. I am trying to open the area scan camera as Vin Acquisition and the line scan camera as GenTL Acquisition. When, I open the camera individually one after the other using CVB++, I do not see any issues, but when I try to open the cameras in two different threads, only the area scan opens and the line scanner thread says, the acquisition stack is already in use. So, my question is it is possible to run both the cameras in two separate threads ?

@keerthitheja Please dedicate a specific port for each camera and try again:
Camera1 → port 0
Camera2 → Port 1
The following screenshot demonstrates how to do that in code and in .ini setting for VinDriver:

I am not sure on how porthandling in the GenTL is realized (if at all) BUT:
At least for the vin acquisition you either need to have “AutoSwitchEnabled” set to true in the .ini or take care, that you assign a specific port to the device you want to load.
Usually if not given any port, Port0 will be used for the first device thus blocking it for the next device.
You would have to either switcht the device to a port > 0 after loading it or pass the desired port as argument into the Open().

If you try to load the linescanner first, what is the result then?


hi @Chris,
I am currently looking for the area scan and line scan camera’s based on their MAC Address from the discovery information and then I am opening the devices based on their discovery tokens.

If I try to load the line scanner first, then the area scanner throws an error saying that, acquisition in use.

This issue I am seeing only when opening the area scan as Vin Acquisition.

Now, I changed the acquisition to GenTL for both the cameras and I am seeing no issues. I am able to get the images and save them to the disk.

This underlines my suspicion, that the vin is loaded on Port0 thus blocking it for other devices even if loaded over the GenTL.
Just pass ‘1’ as port in the Open() function when loading the vin device and everything should be fine.

@Chris STOP! :kissing_smiling_eyes:

The GenTL Stack does not use the Genicam.ini.
This means there is no need for “Porthandling” in anyway.

Hi @keerthitheja
The a discovery token (i.e. Cvb::DiscoveryInformation::AccessToken()) defines a connection from interface to device.
So opening 2 cameras in parallel is fine (however some technologies such as U3V don’t react kindly to it, GigEVision is fine though.
But we do not exactly know how the camera reacts. This might be a race condition (we have seen race conditions during the ownership reporting of cameras).

So … what to do:
Simple. (This will also make your application “U3V” ready).

  1. Start your discovery.
  2. Open all cams in serially.
  3. Then start your 2 image acquisition threads and pass the Cvb::DevicePtr to these threads.

BUT using one of the devices as “Vin Acquisition” should fall back to the ini or am I wrong?
At least this should fall back to loading the driver and blocking Port 0?!
Obviously this problem does not happen if both devices are changed to GenTL thats why I suspected the port handling to be the problem

Hi @c.hartmann
Thank you for the reply.

This is exactly what I am doing currently. After opening the cameras serially, I am passing the device pointer to the thread and starting the streams. It works fine.

1 Like

Made a little FAQ about this.

Thanks, that helps but still… using

IGrab2 / Cvb::AcquisitionStack::Vin - without Cvb::DeviceFactory::Discover - Yes, the .ini is used.
IGrab2 / Cvb::AcquisitionStack::Vin - with Cvb::DeviceFactory::Discover - No, the .ini is not used.

Only implies, that the ini is not always used (thus my “AutoSwitchEnabled” hint is invalid).
But still, Port 0 might be blocked after Opening the first camera thus loading the next one might fail or am I getting something wrong here?

1 Like

This is the wrong place to discuss this, but this application is about the GenTL Stack.

And if Discovery is used, the whole “Port” concept disappears.
And IGrab3/GenTL Stack never had a concept of “Port”.

Well I think the forum is a great place for this as this might be something more people are puzzled about. Still, this thread in particular might not be the best place but I dont know where else to put it and I am just too curious.
The application is not all about the GenTL stack if I interprete this statement correctly:

Also the “Port” concept might dissappear when using the “Discovery” BUT DeviceFactory:.Open() still has the concept as an overload:

We also had issues in the past with this exact method not handling the port changes correctly, this is why I am so stuck to this.


Sorry i skipped the part about mixing stack, but in both cases discovery is used.
And a discovery token has no information about other cameras.
Therefore there is no port switching.

We catch this behaviour and throw in these case:

    static DevicePtr OpenPort(const String & provider, int port)
      if (Internal::IsAccessToken(provider))
        throw std::logic_error("access tokens do not support port or board switch");

I.e. no port switching with discovery.

1 Like

Thank you for the clarification :heart: