Tom*_*son 5 c++ concurrency multithreading thread-safety quantlib
我找不到任何明确描述 QuantLib 线程安全属性的文档(或没有它们!)。QuantLib配置文档列出了许多与线程安全相关的编译时选项,从中我推断,默认情况下,QuantLib 并不完全是线程安全的。
特别是,有:
QL_ENABLE_SESSIONS - “如果定义,单例将为不同的会话返回不同的实例。您必须在命名空间 QuantLib 中提供一个 sessionId() 函数并将其与库链接,为每个会话返回不同的会话 ID。默认情况下未定义。”
QL_ENABLE_THREAD_SAFE_OBSERVER_PATTERN - “如果定义,将使用观察者模式的线程安全(但性能较低)版本。如果您想通过 JVM 或 .NET 生态系统或任何环境中的 SWIG 层使用 QuantLib,您应该定义它异步垃圾收集器。默认情况下未定义。”
QL_ENABLE_SINGLETON_THREAD_SAFE_INIT - “定义它以使单例初始化线程安全。默认情况下未定义。与多个会话不兼容。”
如果我想使用 QuantLib,我应该使用哪些选项,以及我应该采取哪些其他步骤:
来自多个线程,但永远不会同时(例如,仅在持有全局锁时)?
同时来自多个线程,但不在它们之间共享任何对象?
同时来自多个线程,在它们之间共享对象?
我的应用程序的自然结构是一个有向无环图,在一端输入一个恒定的市场数据流,用于计算和更新各种对象,并在另一端生成一个估计价格流。我非常希望能够让多个内核并行工作,因为有些计算需要很长时间。
该应用程序将主要用 Java 编写,与 QuantLib 接口的 C++ 部分最少。我不打算使用 SWIG 包装器。我很高兴在没有 Java 垃圾收集器帮助的情况下对 QuantLib 对象进行内存管理。
编辑!如果您决定设置这些选项中的任何一个,那么在 unix 上,将相应的标志设置为 ./configure:
--enable-sessions
--enable-thread-safe-observer-pattern
--enable-thread-safe-singleton-init
Run Code Online (Sandbox Code Playgroud)
SmallChess 的答案与事实相差不远。QuantLib 中几乎没有锁或安全网,因此大多数人如果需要在处理器上分配计算,就会使用多处理——并且有充分的理由。
对于那些想要更多了解而不是支持在 QuantLib 中使用多线程的人:
无论您做什么,如果可能的话,启用为您提供一定安全性的配置开关,例如用于单例的线程安全初始化的开关(需要注意的是,请参见下文);
如果多个线程不共享任何对象,并且不尝试修改全局变量(例如评估日期),则可能会同时运行多个线程(查找从 Singleton 继承的类以获取全局变量列表)。
如果您需要不同线程的不同评估日期,您可以使用另一个编译开关来构建 QuantLib,以便单例实际上不是单例,但每个线程都有一个实例。注意:此开关与单例的线程安全初始化不兼容。您仍然不应该在线程之间共享对象。
如果您想共享对象,您可能会遇到比其价值更多的麻烦。问题是:(1)对基础数据(例如曲线)的任何更改都会触发重新计算;(2)重新计算(例如曲线的自举)不会立即执行,而是仅在需要时执行,即在调用某些曲线方法时执行。这意味着您必须将各个步骤分开:首先,设置任何引号的值并确保没有任何进一步的更改;然后,绕过曲线并触发重新计算,例如通过在某个日期询问折扣系数;最后,将曲线传递给工具并为其定价。在计算过程中更改值将导致在计算过程中执行引导程序;并且在计算之前不触发完整的构建可能会导致两个仪器同时触发两个引导程序,这对任何相关方来说都不会有好结果。
正如我所说,这可能带来的麻烦大于其价值。理想情况下,不要在线程之间共享对象,也不要触及全局变量。否则,更喜欢多处理。