多线程 + 多相机并行推理:必须每个线程独立拥有一个 cv::dnn::Net 对象,不能多个线程共用同一个 Net! 也就是:线程数 = Net 实例数量。
cpp
cv::dnn::Net netCam5,netCam6,netCam7,netCam8,netCam11,netCam12;
netCam5 = readNetFromONNX(onnx_seg_path);
netCam5.setPreferableBackend(DNN_BACKEND_OPENCV);
netCam5.setPreferableTarget(DNN_TARGET_CPU);
netCam6 = readNetFromONNX(onnx_seg_path);
netCam6.setPreferableBackend(DNN_BACKEND_OPENCV);
netCam6.setPreferableTarget(DNN_TARGET_CPU);
netCam7 = readNetFromONNX(onnx_seg_path);
netCam7.setPreferableBackend(DNN_BACKEND_OPENCV);
netCam7.setPreferableTarget(DNN_TARGET_CPU);
netCam8 = readNetFromONNX(onnx_seg_path);
netCam8.setPreferableBackend(DNN_BACKEND_OPENCV);
netCam8.setPreferableTarget(DNN_TARGET_CPU);
原因分析:
- 底层原因(OpenCV DNN 不管 CPU/CUDA 后端都适用)
cv::dnn::Net 不是线程安全。
Net 内部包含:计算图、中间张量缓存、推理上下文、GPU 显存上下文。
多线程同时调用同一个 Net 的 setInput() / forward(),会发生:
内存覆盖、张量错乱
随机崩溃、偶发断言报错(就是你之前遇到的各种 Reshape /assign 异常)
推理结果随机错乱、mask / 检测框忽对忽错
简单一句话:同一个 Net 不能被多个线程并发调用 forward。
2.每个线程内部只操作自己专属的 Net,无锁,并发安全。
优点:不需要互斥锁,并发性能最好,逻辑简单稳定,工业视觉首选。
缺点:CPU 推理:每个 Net 会在内存里加载一份模型权重,内存占用成倍增加。