Ruby中冻结的线程组异常
我使用嵌入式Ruby(Ruby版本1.8.6)从CPP调用Ruby代码。我将一个Ruby代码传递给rb_eval_string(),它将创建一个新线程。多次运行此cpp代码(大约20次)会导致内核转储SIGSEGV(信号11),stacktrace显示导致内核转储的原因是eval.c的rb_eval_string()中引发了异常:Ruby中冻结的线程组异常,ruby,Ruby,我使用嵌入式Ruby(Ruby版本1.8.6)从CPP调用Ruby代码。我将一个Ruby代码传递给rb_eval_string(),它将创建一个新线程。多次运行此cpp代码(大约20次)会导致内核转储SIGSEGV(信号11),stacktrace显示导致内核转储的原因是eval.c的rb_eval_string()中引发了异常: #5 <signal handler called> #6 rb_longjmp (tag=6, mesg=365482760) at eval.c:
#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
上述例外情况的原因是什么?应该做些什么来避免它
下面是我传递给rb_eval_string_protect()的ruby代码:
“需要‘监视器’\n”
“需要“套接字”\n”
“包括RubyInterpreter\n”
“$rubyPort=11111;\n”
“$isEmbeddedLoopReady=false;\n”
“$hasEmbeddedLoopFinished=false;\n”
“def newServer()\n”
“虽然为true\n”
“开始\n”
server=TCPServer.new(\'localhost\',$rubyPort);\n
“中断;\n”
“救援;\n”
“$rubyPort+=1;\n”
“结束\n”
“结束\n”
“返回服务器\n”
“结束\n”
“$rubyMonitor=Monitor.new\n”
“类多重映射\n”
“def初始化()\n”
“@mHashMap=Hash.new\n”
“结束\n”
“def存储(值)\n”
“$rubyMonitor.synchronize do\n”
“键=值。\u\u id\u\n”
“如果(nil==@mHashMap[key])\n”
“@mHashMap[key]=Array.new()\n”
“结束\n”
“elem=@mHashMap[键]\n”
“元素推送(值);\n”
“结束\n”
“结束\n”
“def删除(值)\n”
“$rubyMonitor.synchronize do\n”
“键=值。\u\u id\u\n”
“如果(@mHashMap[key]!=nil)\n”
“elem=@mHashMap[key].pop();\n”
“如果(@mHashMap[key].length==0)\n”
“@mHashMap.delete(键)\n”
“结束\n”
“返回元素;\n”
“结束\n”
“结束\n”
“返回零\n”
“结束\n”
“结束\n”
“类MyThread<线程\n”
“def初始化(第一个任务)\n”
“超级()\n”
“@owner=firstTask\n”
“结束\n”
“def getOwner()\n”
“返回@owner\n”
“结束\n”
“结束\n”
“def embeddedLoop()\n”
“keepRunning=false;\n”
“服务器=新闻服务器();\n”
“$isEmbeddedLoopReady=true;\n”
“如果(session=server.accept),则\n”
“keepRunning=true;\n”
“结束;\n”
“$runningTaskCount=0\n”
“while(keepRunning==true)\n”
“会话。读取(1);\n”
“rubyTask=RubyInterpreter.getRubyTask()\n”
“如果(rubyTask!=nil)\n”
“$runningTaskCount+=1\n”
“s=MyThread.new(rubyTask){\n”
“开始\n”
“rubyTask.execute()\n”
“$runningTaskCount-=1\n”
“营救标准错误\n”
“rubyTask.notifyCompletion()\n”
“$runningTaskCount-=1\n”
“结束\n”
“}\n”
“否则\n”
“keepRunning=false\n”
“结束\n”
“结束\n”
“$hasEmbeddedLoopFinished=true\n”
“结束\n”
“$embeddedLoopThread=Thread.new{\n”
“开始\n”
“embeddedLoop()\n”
“营救标准错误\n”
“放置\“****严重内部错误****\”\n”
“放置$!.backtrace.join(\“\\n\”)\n”
“结束\n”
“}\n”
“而($isEmbeddedLoopReady==false)\n”
“结束\n”;
由于我正在从Ruby代码调用cpp方法RubyInterpreter.getRubyTask(),因此我定义了以下内容:
sModule=rb_define_模块(“RubyInterpreter”);
rb_gc_寄存器_地址(&S模块);
rb_define_singleton_方法(sModule,“getRubyTask”,reinterpret_cast(RubyInterpreter::getRubyTask),0)
getRubyTask()返回一个简单的Ruby任务,例如puts'Hello!'
异常似乎是从eval.c的rb_thread_start_0()抛出的
谢谢,
Aarti没有任何源代码,我们真的帮不了你,对不起。我现在已经提供了源代码。请你帮忙。
Exception thrown is: (eval):223:in `initialize': can't start a new thread (frozen ThreadGroup)
"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";