涉及线程的c ++ / Java之间的函数完成信号

时间:2012-09-19 20:54:36

标签: java c++ multithreading java-native-interface

在C ++ JNI函数(下面包含半伪)中,在client_ = new VClient(&callback_)行创建了至少一个(可能还有两个)其他线程。我认为这个函数的完成就足够了,但显然当在此之后“立即”调用下一个函数(另一个JNICALL函数)时,它会导致一个SEGFUALT(“立即”在引号中,因为函数被调用的速度很快有人可以按下一个按钮)。我认为这是因为在Init函数返回并且调用下一个函数时,创建new VClient尚未完成,因为client_正在下一个函数中使用。

我对所有这些线程业务都很陌生,我不确定这是否是正确的思路。我习惯于按顺序执行代码,因此当代码从client_行开始移动时,这是因为该行的所有内容都已完成。代码是否可以从此行继续,并在完全创建新VClient之前从JNI Init函数返回?如果是这样,我将如何让这个函数等到类/对象完成后才开始?

JNIEXPORT void JNICALL Java_com_ClassDir_Init(JNIEnv *env, jobject obj)
{
  LOGI("%s", __PRETTY_FUNCTION__);
  if(!client_)
  {
    LOGI("Initializing client");
    client_ = new VClient(&callback_);
    [Bunch of JNI/JAVA class and methodID lookup and saving]
  }
  else
    LOGI("Client already initialized");
}

* callback_是一个处理向JNI / JAVA发送枚举类型信号以更新程序进度的类。

2 个答案:

答案 0 :(得分:1)

你说VClient构造函数创建了线程。 创建线程是一个同步进程:VClient ctor的执行在线程完全创建之前不会继续,并且很可能也会启动,因为我没有看到任何其他方法调用VClient istance做。什么是同步,是线程的开始。它并不意味着“完全可操作”,只是您的主线程指示创建的线程开始在其自己的上下文中运行。当新线程的执行循环被设置并且输入完全异步(对你的VClient构造)并且直到线程调度。因此,如果您的“下一个JNI函数”尝试调用该线程并在那里使用某些资源,那么该资源必须已经可用(这意味着您希望新线程已经进展到使其可用的程度)并且访问必须保护该资源以进行线程安全访问。

所以你需要在这个线程业务中变得不那么新:-)查找两个基本构建块:

  1. 等待条件(也称为“阻止条件变量”)。在调用VClient ctor之后,您将等待一个需要传递给线程的对象。线程将在完成基本工作时通知条件,从而在第一个线程中解锁等待。
  2. 互斥即可。每当有一个资源(数据结构)可以通过执行多个线程同时访问时,您需要在访问代码之前锁定互斥锁并在之后解锁。后来到达的线程将阻塞锁,直到第一个线程完成。否则,当两个线程试图修改相同的内存时,您将得到奇怪的结果或直接崩溃。
  3. 这些在每个操作系统和每个框架的各种API中实现的方式不同。即使是同一操作系统上的不同框架也会有所不同。但哲学是平等的。

    顺便说一句,我理所当然地认为,当{em>“下一个JNI函数”试图使用它时,client_的声明方式不会超出范围。这可能意味着JNI实现中的全局变量 - 我没有看到本机代码的任何类包装器。

答案 1 :(得分:0)

没有。在Client构造函数存在之前,调用'new Client()'的代码行不会继续到下一行。执行是顺序的。你的问题在别处。