1

現在V8で実験中です。あるスレッドで(おそらく長時間実行される)javascriptを実行し、別のスレッドから自由に「優雅に」実行を終了できるようにしたいと考えています。

ロッカーの概念と 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::V8::GetCurrentThreadId()andv8::V8::TerminateExecution(int)メソッドは V8 API から削除されました。それらを使用しないことをお勧めします。プリエンプション機能も、この世界ではおそらく長くはありません。

代わりに、単に を呼び出しますv8::V8::TerminateExecution(v8::Isolate*)。また、ブレーカー スレッドで Isolate をロックしないでください。これを行うと、ランナー スレッドが Isolate を解放するまでブロックされ、スクリプトの実行が終了するまでロックされません。

于 2013-10-16T16:34:40.230 に答える