11

読み取り専用でのみ使用されているイメージをスレッド間で共有しようとしています。通常、私はboost::shared_ptrsでこの種のことを行いますが、cv::Matはすでにその下の参照カウントコンテナーであるため、スレッドセーフへの参照に基づいてスレッドセーフであると仮定して、同じ方法で使用しようとしていますここでの参照カウント:

ただし、実際にはスレッドセーフではないことを示す可能性のある問題が発生しています。その割り当ては非アトミックです。元のオブジェクトが既に破棄されていることを意味する参照カウントのインクリメント内で seg-fault が発生することがあります。

したがって、具体的な質問は次のとおりです。

  • cv::Mat 割り当てはアトミックですか?
4

2 に答える 2

5

具体的な質問、短い答え: はい。

cv::Mat 実装の詳細は、core/src/matrix.cppおよびで確認できます。include/.../core/core.hpp

OpenCV ソースからのいくつかのコードの抜粋:

 if( refcount )
        CV_XADD(refcount, 1);

CV_XADD は、アトミック テスト アンド インクリメントです。

inline void Mat::addref()
{ if( refcount ) CV_XADD(refcount, 1); }

inline void Mat::release()
{
    if( refcount && CV_XADD(refcount, -1) == 1 )
        deallocate();
    data = datastart = dataend = datalimit = 0;
    size.p[0] = 0;
    refcount = 0;
}

追加

スマート ポインターは一定レベルのスレッド セーフを提供しますが、可能なすべてのシナリオで完全にスレッド セーフであるとは限りません。具体的には、別のスレッドによって破棄されると同時に共有 ptr をコピーしようとすると、失われます。これは実装上のバグではなく、速度と有用性の間の設計上のトレードオフです。

すべての主要な共有 ptr 実装 (boost、stl) は、このアプローチに従います。

于 2012-05-19T17:57:44.267 に答える