使用v8 :: Locker的正确方法是什么,为什么我必须使用它? [英] What is the correct way to use v8::Locker, and why must I use it?

查看:143
本文介绍了使用v8 :: Locker的正确方法是什么,为什么我必须使用它?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆