1

我目前正在尝试使用 V8。我希望能够在一个线程中运行一些(可能是长时间运行的)javascript,然后能够从另一个线程随意“优雅地”终止执行。

我编写了这个简单的代码片段来测试 Lockers 的概念和 TerminateExecution 的用法:

void breaker( Isolate* isolate, int tid ) {

    getchar();      //wait for keyboard input on stdin

    std::cout << "Breaking V8 execution" << std::endl;

    v8::Locker locker( isolate );       //lock the isolate
    v8::V8::TerminateExecution( tid );  //and terminate it
}

int main( int argc, char **argv ) {

    if( argc != 2 ) {
        std::cout << "No script name given" << std::endl;
        return 1;
    }

    Isolate* isolate = Isolate::New();              //create a new isolate
    Isolate::Scope isolateScope( isolate );         //enter it

    v8::Locker locker( isolate );                   //lock the isolate
    v8::Locker::StartPreemption( 100 );             //and start preemption

    v8::HandleScope handle_scope( isolate );        //open a new handle scope


    /*** inject a console object into the global context ***/
    v8::Handle<v8::ObjectTemplate> globalTemplate = v8::ObjectTemplate::New();

    Handle<Context> context = Context::New( NULL, globalTemplate );
    v8::Context::Scope context_scope( context );

    Console* console = new Console;
    Handle<Object> jsConsole = wrap_console( isolate, console );
    expose_property( jsConsole, String::New( "log" ), InvocationCallback( Console::consoleLog ) );
    context->Global()->Set( String::New( "console" ), jsConsole, v8::ReadOnly );
    /*******************************************************/


    //read a javascript file supplied via console
    std::string contents = read_file( argv[1] );
    v8::Handle<v8::String> js = v8::String::New( contents.c_str() );

    v8::TryCatch try_catch;
    v8::Handle<v8::Script> script = v8::Script::Compile( js );

    if( script.IsEmpty() ) {
        report_exception( try_catch );
    }

    //start the breaker thread
    std::thread th( breaker, isolate, v8::V8::GetCurrentThreadId() );

    log_info( "running script" );
    script->Run();
    log_info( "Script execution finished" );

    th.join();
}

但是,我总是在terminateExecution()通话中遇到段错误。我在这里做错了什么?

谢谢你的帮助

4

1 回答 1

7

和方法已从 V8 API 中删除v8::V8::GetCurrentThreadId()v8::V8::TerminateExecution(int)我建议你不要使用它们。抢占功能对于这个世界来说可能也不长。

相反,只需调用v8::V8::TerminateExecution(v8::Isolate*). 并且不要将隔离锁定在您的中断线程中,因为这样做会阻塞,直到您的运行线程释放隔离,在脚本执行完成之前它不会这样做。

于 2013-10-16T16:34:40.230 回答