我正在编写一个使用JNA将Java的工作委派给本机C ++库的服务。 C ++库对计算量大的任务进行异步调用,然后在该任务完成时获得回调(在不同的OS线程上)。我想将这项工作的结果路由回JVM中的正确线程。
我想知道的是,可以确保JVM线程ID始终与本机thread_id具有一对一的映射吗?即如果我通过
在C ++中记录线程IDstd::this_thread::get_id()
然后启动一些昂贵的工作并在cv上阻塞,一旦工作完成,线程仍将存在,并且我将能够正确地将结果返回给JVM。是否会像JIT,GC之类的幕后JVM或停止收集世界的东西成为这种模式的原因?
答案 0 :(得分:5)
JLS,JVM规范或Javadocs中未指定答案。
实际上,它可能是特定于平台的。例如,在Solaris的JVM中,可以(或可以)将用户空间线程映射到内核空间线程:参见this document。尚不清楚这对本机线程ID意味着什么。
那么对于您使用的JVM,线程的本机thread_id
是否会保持不变?
只有一种方法可以确保:下载JVM源代码并进行检查。
警告:这太可怕了!
(而且,您可能应该以此为暗示,如果您必须求助于StackOverflow能否正常工作,就不应该做这种事情!) < / p>
答案 1 :(得分:0)
对我来说,这似乎是一个糟糕的设计,需要您了解JVM的工作原理。
如果您仍然将一些Java数据封送至C ++层,为什么不封送一个回调+上下文呢?当C ++线程完成数据处理后,它将使用提供的上下文并在Java层中调用Java回调-将结果推回Java线程。
C ++层对Java线程的工作方式一无所知-它要做的就是调用一个回调并让该回调处理实现细节。
实际上,我过去已经做过几次,但是使用C#和P / Invoke,可以轻松地将C#函数编组为C函数指针。我相信JNI也有可能。