当我从 C# 代码调用 C++ 代码时,它是线程安全的吗?
Posted
技术标签:
【中文标题】当我从 C# 代码调用 C++ 代码时,它是线程安全的吗?【英文标题】:When I call C++ code from C# code, is it thread-safe? 【发布时间】:2013-12-20 13:51:34 【问题描述】:我有一个 C# 项目,我需要确定给定日期是否是给定国家/地区的假期。为此,我可以使用QuantLib 中的日期和日历功能。 QuantLib 是用 C++ 编写的,因此我编写了一个包装器来调用此代码。我想知道我使用的代码是否是线程安全的。
以下是我在 C++ 中使用的 QuantLib 调用,以确定给定日期是否为假日:
extern "C" _declspec(dllexport) int isHoliday(int year, int month, int day,
int trueValue, int falseValue, int errorValue)
try
QuantLib::Calendar cal = QuantLib::UnitedStates();
QuantLib::Date date(day, (QuantLib::Month)month, year);
return cal.isHoliday(date) ? trueValue : falseValue;
catch(...)
return errorValue;
这是我用来调用 C++ 代码的 C# 签名:
[DllImport("QuantLibHelpers.dll", CallingConvention = CallingConvention.Cdecl)]
private static extern int isHoliday(int year, int month, int day,
int trueValue, int falseValue, int errorValue);
我能找到的关于 QuantLib 代码最多的是here。那里没有任何东西看起来是线程不安全的,但我不能确定。更一般地说,不管我使用 QuantLib,调用像这样的 C++ 代码是线程安全的吗?是否有可能一个线程在创建日期对象时被另一个线程中断,该线程以某种方式破坏了第一个日期对象?我知道如果这段代码确实是线程不安全的,我可以锁定对 C# isHoliday() 静态函数的所有调用。
请注意,我的代码可以正常工作。
我知道QLNet 是 QuantLib 的 .Net 端口。我更喜欢使用 QuantLib,因为它似乎有更好的支持。
【问题讨论】:
你总是可以在你的 C++ 包装器中添加互斥调用,例如std::lock_guard<std::mutex>
in C++11
QuantLib 是否有任何已知的线程问题?如果不是,您可以遵循 C++ 最佳实践,仅在每次调用的基础上保留任何实例。
【参考方案1】:
QuantLib 中有很多东西不是线程安全的(这表明 Sean 的回答是正确的:总是检查!)但是这个特定的东西是安全的,除了一件事:@ 的第一个构造987654321@ 实例将在构造函数中初始化一个静态变量,因此您可能需要处理这种情况。一旦构建了第一个实例,就可以安全地在并行线程中构建其他实例。
Date
实例的构造和对isHoliday
的调用都是安全的。
【讨论】:
我正要问你是怎么知道的,但后来我看到了你的用户名。听起来我所要做的就是在启动时以线程安全的方式调用我的 C++ 代码。谢谢路易吉!【参考方案2】:这完全取决于 C++ 库的实现。
这与使用 C# 程序集没有什么不同。当你在一个对象上调用一个方法时,你怎么知道它是否是线程安全的?答案是你不需要,你必须查看库文档。
如果您不确定,那么您可以随时在自己的代码中添加线程安全包装器,以便序列化对 API 的调用。
【讨论】:
以上是关于当我从 C# 代码调用 C++ 代码时,它是线程安全的吗?的主要内容,如果未能解决你的问题,请参考以下文章
当我从 C 和 C# 过渡到 C++ 时,我可以期待有啥不同?
在 C++ 代码中调用 TerminateThread 后在 C# 代码中检测到 FatalExecutionEngineError