在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发送枚举类型信号以更新程序进度的类。
答案 0 :(得分:1)
你说VClient
构造函数创建了线程。 创建线程是一个同步进程:VClient
ctor的执行在线程完全创建之前不会继续,并且很可能也会启动,因为我没有看到任何其他方法调用VClient istance做。什么是不同步,是线程的开始。它并不意味着“完全可操作”,只是您的主线程指示创建的线程开始在其自己的上下文中运行。当新线程的执行循环被设置并且输入完全异步(对你的VClient构造)并且直到线程调度。因此,如果您的“下一个JNI函数”尝试调用该线程并在那里使用某些资源,那么该资源必须已经可用(这意味着您希望新线程已经进展到使其可用的程度)并且访问必须保护该资源以进行线程安全访问。
所以你需要在这个线程业务中变得不那么新:-)查找两个基本构建块:
这些在每个操作系统和每个框架的各种API中实现的方式不同。即使是同一操作系统上的不同框架也会有所不同。但哲学是平等的。
顺便说一句,我理所当然地认为,当{em>“下一个JNI函数”试图使用它时,client_
的声明方式不会超出范围。这可能意味着JNI实现中的全局变量 - 我没有看到本机代码的任何类包装器。
答案 1 :(得分:0)
没有。在Client构造函数存在之前,调用'new Client()'的代码行不会继续到下一行。执行是顺序的。你的问题在别处。