Я пишу веб-приложение с использованием Play Framework 2.1, которое использует библиотеки OpenCV (2.4.6). У меня не было проблем с компиляцией OpenCV и получением финального .jar, но есть одно замечание, которое меня беспокоит учебник по Java / Scala для OpenCV:
Обратите внимание на призыв к
System.loadLibrary(Core.NATIVE_LIBRARY_NAME)
, это
Команда должна быть выполнена ровно один раз для каждого процесса Java перед использованием
любые родные методы OpenCV. Если вы не позвоните, вы получите
Неудовлетворенные ссылки. Вы также получите ошибки, если попытаетесь загрузить
OpenCV, когда он уже был загружен.
Я знаю, что Play Framework многопоточный и потоки повторно используются между запросами. Есть ли способ для меня позвонить loadLibrary
функционировать, когда порождаются отдельные потоки? Или я неправильно понимаю, как работает пул потоков, и я должен загружать библиотеку один раз за запрос? Какой правильный подход здесь?
System.loadLibrary
код в классе глобальной конфигурации, который заставит все потоки совместно использовать библиотеку. Библиотека не является поточно-ориентированной, поэтому я думаю, что если я это сделаю, это просто случайность, ожидающая …
Кажется, нет проблемы — «Эта команда должна выполняться ровно один раз для Java процесс«- достаточно будет вызвать его один раз при запуске приложения, и вам не придется беспокоиться о разных потоки.
Бонус: можно проверить, была ли библиотека уже загружена (даже если она совершенно не нужна), т.е.
def loadedLibs: Seq[String] = {
val libs = classOf[ClassLoader].getDeclaredField("loadedLibraryNames")
libs.setAccessible(true)
import scala.collection.JavaConverters._
libs.get(ClassLoader.getSystemClassLoader())
.asInstanceOf[java.util.Vector[String]]
.asScala
}
def loadOpenCVOnDemand(): Unit = {
val isLoaded = loadedLibs.map(str => str contains "opencv").reduce((x, y) => x || y)
if(!isLoaded) {
System.loadLibrary(Core.NATIVE_LIBRARY_NAME)
}
}
Совсем другая проблема, если функции нативной библиотеки можно вызывать одновременно. В OpenCV это совсем не проблема:
Текущая реализация OpenCV полностью доступна. Это
та же функция, тот же метод константы экземпляра класса, или
Один и тот же непостоянный метод разных экземпляров класса может быть вызван
из разных тем. Кроме того, тот же cv :: Mat может быть использован в
различные потоки, потому что операции подсчета ссылок используют
специфичные для архитектуры атомарные инструкции.
Других решений пока нет …