2015-10-08 3 views
-2

Создали C++-оболочку над некоторой функциональностью OpenCV и экспортировали ее для 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; 

недействительными выполнить (Документ & г) {

  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

no Контекст всегда новый –

+0

эта ошибка не возникает в конфигурации отладки (/ MDd) только в Release (/ MD) –

1

Некоторые проблемы были с Mat &, которые были сохранены в OperationBase и установлены с помощью метода .prepare(). Я C# парень, поэтому для меня «ссылка» - это «общий указатель» не более. Я переписал весь код OperationBase, чтобы не хранить ссылки или указатели на маты, хранящиеся в Контексте, и всегда получать их как Mat * в рамках метода операции. Такой комбо стал потокобезопасным.)

Смежные вопросы