解决由于非线程安全 API 函数而并行发生的分段错误
Posted
技术标签:
【中文标题】解决由于非线程安全 API 函数而并行发生的分段错误【英文标题】:Working around segmentation faults that occur in parallel due to a non-thread-safe API function 【发布时间】:2012-04-20 04:43:52 【问题描述】:我目前正在 MATLAB 中编写一个 MEX 文件,以便使用 MATLAB 2012a 中的 parfor 函数并行运行实验。 MEX 文件执行一些非常简单的数字任务,但依赖于 IBM 的 CPLEX 12.4 API。
虽然我的 MEX 文件按顺序运行,I will inevitably receive "random" segmentation fault when I run in in parallel。在将分段错误的堆栈跟踪发送到 MATLAB 后,他们认为错误源自 C 库中的“putenv()”函数,这显然不是线程安全的。
我没有在 MEX 代码中使用 putenv() 函数,但事实证明,我绝对必须从 CPLEX 12.4 调用的函数之一确实使用了它。我想知道是否有什么办法可以避免此功能导致的分段错误。以前有人建议“锁定我的位”和“使用信号量”,但当谈到这些概念时,我真的有点不知所措。
非常感谢任何建议或指导。
【问题讨论】:
致电 IBM 支持并告诉他们修复他们的库,以便它可以在 2000 年后的机器上有效使用?我猜这个库是不透明的,你没有源代码并且无法重建它? 【参考方案1】:事实证明,由于我同时在我的 MATLAB 代码中使用 CPLEX MATLAB API 和在我的 MEX 代码中使用 CPLEX C API,因此发生了违规。两个 API 都使用 putenv() 函数,该函数不是线程安全的。特别是,只要两个线程尝试同时使用 putenv() 函数(在 MEX 文件或 MATLAB 代码中),就会发生崩溃。
修复方法是使用包并在 C 和 MATLAB 中使用 putenv() 的函数周围添加 mutex_lock / mutex_unlock(即 CPXopenCPLEX 中的 C / Cplex() 在 MATLAB 中)。更多信息和创建 mutex_lock / mutex_unlock 的确切代码可以在following post on the CPLEX forums 中找到
【讨论】:
以上是关于解决由于非线程安全 API 函数而并行发生的分段错误的主要内容,如果未能解决你的问题,请参考以下文章
JavaSE中线程与并行API框架学习笔记——线程为什么会不安全?