2015-10-08 90 views
-2

已經創建了一些OpenCV函數的C++包裝器並將它導出爲PInvoke,可以並行調用它。C++不明白爲什麼這個代碼不是線程安全的

在堅果:

void execute(Document& d) { 

      ScriptConfig conf(d); 
      Context c(conf); 
      OperationManager m; 
      while (c.next()) { 
       unique_ptr<OperationBase> op = m.create(*c.getCurrentOp()); 
// m.create inside ALWAYS creates unique_ptr<OperationBase>(NEW ConcreteOperationBase()); 
//nothing cached 
       op->prepare(&c); 
       op->execute(); 
       op->afterExecute(); 
      } 

     } 

內部業務工作與它的上下文和OpenCV的做一些操作。上下文保存Mat的操作實例。

此代碼不是線程安全的。如果我嘗試使用幾個執行emmidiatly的調用,他們隨機的方式打破對方的工作。這看起來像是操作在無效的墊子上工作。

我檢查操作中的opencv相關代碼是線程安全的 - 沒關係。

當我有將其固定到下面的方式:

mutex _locker; 

空隙執行(文獻& d){

  ScriptConfig conf(d); 
      Context c(conf); 
      OperationManager m; 
      while (c.next()) { 
       _locker.lock(); 
       unique_ptr<OperationBase> op = m.create(*c.getCurrentOp()); 
// m.create inside ALWAYS creates unique_ptr<OperationBase>(NEW ConcreteOperationBase()); 
//nothing cached 
       op->prepare(&c); 
       op->execute(); 
       op->afterExecute(); 
       _locker.unlock(); 
      } 

     } 

無裏是與多線程沒有問題。但這並不是我想要的 - 我必須並行地調用操作!

+0

你能找出不同線程是否同時使用相同的輸入/輸出嗎?每個輸入/輸出使用一個互斥量,或確保線程不共享它們。 – Micka

回答

1

並非所有的「OperationBase」實例並行使用相同的「上下文」?

+0

否上下文始終是新的 –

+0

此錯誤在調試配置(/ MDd)中僅在發佈版(/ MD)中才會發生 –

1

存儲在OperationBase中並使用.prepare()方法設置的Mat &存在一些問題。我是C#人,所以對我來說「參考」是「共享指針」不多。我已經重寫了OperationBase的所有代碼,不要將參數或指向存儲在上下文中的地墊的指針存儲起來,並始終將它們作爲Mat *放在Operation的方法中。這樣的組合變得線程安全。 )

相關問題