Ruby中的Frozen ThreadGroup异常

时间:2013-03-15 12:52:34

标签: ruby

我使用嵌入式Ruby(Ruby版本1.8.6)从CPP调用ruby代码。我将Ruby代码传递给rb_eval_string(),这将创建一个新线程。多次运行此cpp代码(大约20)导致带有SIGSEGV的核心转储(信号11),堆栈跟踪显示核心是由于eval.c的rb_eval_string()中引发异常引起的:

#5  <signal handler called>
#6  rb_longjmp (tag=6, mesg=365482760) at eval.c:4634
#7  0x00002aaaabd7fdc1 in rb_exc_raise (mesg=6) at eval.c:4650
#8  0x00002aaaabd89ae2 in eval (self=365613880, src=367575400, scope=4, file=0x15ad1f99 "(eval)", line=140)
at eval.c:6565
#9  0x00002aaaabd8a631 in rb_eval_string (str=0x2aaaac0bffe0 "<String containing ruby code which is passed to this function>"...)
at eval.c:1707

要在我的CPP代码中处理此异常,我使用rb_eval_string_protect()而不是rb_eval_string()并尝试打印rb_eval_string_protect()返回的状态。通过此更改,SIGABRT(信号6)仍然会发生崩溃,并且使用VALUE对象(状态)在我的CPP代码中显示以下execption消息,该对象由rb_eval_string_protect()填充:

Exception thrown is: (eval):223:in `initialize': can't start a new thread (frozen ThreadGroup)

上述例外的原因是什么?应该怎么做才能避免呢?

以下是我传递给rb_eval_string_protect()的ruby代码:

"require 'monitor'\n"
"require 'socket'\n"
"include RubyInterpreter\n"

"$rubyPort = 11111;\n"
"$isEmbeddedLoopReady = false;\n"
"$hasEmbeddedLoopFinished = false;\n"

"def newServer()\n"
  "while true\n"
    "begin\n"
      "server = TCPServer.new(\"localhost\", $rubyPort);\n"
      "break;\n"
    "rescue;\n"
      "$rubyPort += 1;\n"
    "end\n"
  "end\n"
  "return server\n"
"end\n"

"$rubyMonitor = Monitor.new\n"

"class MultiMap\n"

  "def initialize()\n"
    "@mHashMap = Hash.new\n"
  "end\n"

  "def store(value)\n"
    "$rubyMonitor.synchronize do\n"
       "key = value.__id__\n"
      "if (nil == @mHashMap[key])\n"
        "@mHashMap[key] = Array.new()\n"
      "end\n"
      "elem =  @mHashMap[key]\n"
      "elem.push(value);\n"
    "end\n"
  "end\n"

  "def delete(value)\n"
    "$rubyMonitor.synchronize do\n"
      "key = value.__id__\n"
      "if (@mHashMap[key] != nil)\n"
        "elem = @mHashMap[key].pop();\n"
        "if(@mHashMap[key].length == 0)\n"
          "@mHashMap.delete(key)\n"
        "end\n"
        "return elem;\n"
      "end\n"
    "end\n"
    "return nil\n"
  "end\n"

"end\n"

"class MyThread < Thread\n"

"  def initialize(firstTask)\n"
"    super()\n"
"    @owner = firstTask\n"
"  end\n"

"  def getOwner()\n"
"    return @owner\n"
"  end\n"

"end\n"

"def embeddedLoop()\n"
"  keepRunning = false;\n"
"  server = newServer();\n"
"  $isEmbeddedLoopReady = true;\n"
"  if (session = server.accept) then\n"
"     keepRunning = true;\n"
"  end;\n"

"  $runningTaskCount = 0\n"
"  while(keepRunning == true)\n"
"    session.read(1);\n"
"    rubyTask = RubyInterpreter.getRubyTask()\n"
"      if(rubyTask != nil)\n"
"          $runningTaskCount += 1\n"
"          s = MyThread.new(rubyTask){\n"
"          begin \n"
"            rubyTask.execute()\n"
"            $runningTaskCount -= 1\n"
"          rescue StandardError\n"
"            rubyTask.notifyCompletion()\n"
"            $runningTaskCount -= 1\n"
"          end\n"
"        }\n"
"      else\n"
"        keepRunning = false\n"
"      end\n"
"  end\n"
"  $hasEmbeddedLoopFinished = true\n"
"end\n"

"$embeddedLoopThread = Thread.new {\n"
"  begin \n"
"    embeddedLoop()\n"
"  rescue StandardError\n"
"    puts \"**** CRITICAL INTERNAL ERROR ****\"\n"
"    puts $!.backtrace.join(\"\\n\") \n"
"  end \n"
"  }\n"
"  while($isEmbeddedLoopReady == false)\n"
"  end \n";

因为我从Ruby代码调用了一个cpp方法RubyInterpreter.getRubyTask(),所以我定义了以下内容: sModule = rb_define_module(“RubyInterpreter”); rb_gc_register_address(安培; sModule); rb_define_singleton_method(sModule,“getRubyTask”,reinterpret_cast(RubyInterpreter :: getRubyTask),0);

RubyInterpreter.getRubyTask()返回一个简单的Ruby任务,例如puts'Hello!'

似乎从eval.c的rb_thread_start_0()抛出异常。

谢谢, 阿尔蒂

0 个答案:

没有答案