使用v8 :: Locker的正确方法是什么,为什么我必须使用它? [英] What is the correct way to use v8::Locker, and why must I use it?
问题描述
我正在尝试使用NDK将v8嵌入Android应用程序中.
I'm trying to embed v8 in an Android application using NDK.
我有一个看起来像这样的JNI模块(未显示JNI映射代码):
I have a JNI module that looks something like this (JNI mapping code not shown):
#include <jni.h>
#include <android/log.h>
#include <v8.h>
using namespace v8;
static jlong getMagicNumber() {
HandleScope handle_scope;
Persistent<Context> context = Context::New();
Context::Scope context_scope(context);
Handle<String> source = String::New("40 + 2");
Handle<Script> script = Script::Compile(source);
Handle<Value> result = script->Run();
context.Dispose();
return result->NumberValue();
}
我第一次运行getMagicNumber
时,它会正确运行并返回42.第二次尝试运行它时,它会崩溃.
The first time I run getMagicNumber
, it correctly runs and returns 42. The second time I try to run it, it crashes.
具体来说,在v8的isolate.h
中看到的此ASSERT
失败:
Specifically, this ASSERT
seen in v8's isolate.h
fails:
// Returns the isolate inside which the current thread is running.
INLINE(static Isolate* Current()) {
Isolate* isolate = reinterpret_cast<Isolate*>(
Thread::GetExistingThreadLocal(isolate_key_));
ASSERT(isolate != NULL);
return isolate;
}
听起来很像此问题 ,建议使用v8::Locker
获得对隔离株的排他性访问".
It sounds a lot like this problem, which suggests using v8::Locker
to obtain "exclusive access to the isolate".
通过在getMagicNumber
的顶部添加简单的Locker l;
,不再发生崩溃.当我不注意时,容易修复的问题很容易崩溃.
By adding a simple Locker l;
to the top of getMagicNumber
, the crash no longer occurs. Problems that fix themselves that easily tend to break themselves when I'm not paying attention.
对于为什么它可以解决我的问题,我只有最脆弱的理解,并且我收到编译器警告,指出我已不赞成使用v8::Locker
.推荐的方法是为它提供v8::Isolate
作为v8::Locker
的构造函数的参数,但是我不知道我应该如何获得"隔离株.
I only have the most tenuous understanding of why this fixes my problem, and I'm getting compiler warnings that I'm using v8::Locker
in a deprecated fashion. The recommended method is to provide it with a v8::Isolate
as an argument to v8::Locker
's constructor, but I have no idea how I'm supposed to "obtain" an isolate.
最终:根据v8的当前状态以及为什么,解决该问题的正确方法是什么?
Ultimately: What is the proper way to solve this problem according to the current state of v8, and why?
推荐答案
据我所知,V8隔离是V8运行时的一个实例,具有一个堆,一个垃圾收集器以及零个或多个V8上下文.隔离不是线程安全的,必须通过v8::Locker
保护.
As I understand it, a V8 isolate is an instance of the V8 runtime, complete with a heap, a garbage collector, and zero or more V8 contexts. Isolates are not thread-safe and must be protected via v8::Locker
.
通常,要使用V8,您必须首先创建一个隔离:
In general, to use V8 you must first create an isolate:
v8::Isolate* isolate = v8::Isolate::New();
然后,使用与任何线程的隔离:
Then, to use the isolate from any thread:
v8::Locker locker(isolate);
v8::Isolate::Scope isolateScope(isolate);
此时,线程拥有隔离符,可以自由创建上下文,执行脚本等.
At this point the thread owns the isolate and is free to create contexts, execute scripts, etc.
现在,对于非常简单的应用程序来说,V8提供了默认的隔离并放宽了锁定要求,但是只有始终从同一线程访问V8时,才可以使用这些拐杖.我的猜测是您的应用程序失败,因为第二次调用是从另一个线程进行的.
Now, for the benefit of very simple applications, V8 provides a default isolate and relaxes the locking requirement, but you can only use these crutches if you always access V8 from the same thread. My guess is that your application failed because the second call was made from a different thread.
这篇关于使用v8 :: Locker的正确方法是什么,为什么我必须使用它?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!