简单的TCL挂起
我使用非常简单的TCL脚本来重现我的问题。我在windows 7上运行activeTCL 8.6.4.1。我使用一个简单的批处理文件(loop.bat),它在循环中调用tcl脚本(1.tcl)。然后,该脚本执行一些"放置"操作。并打开另一个TCL shell来调用另一个TCL脚本(2.tcl)。第二个脚本执行两次"put",一次在标准输出上,一次在标准输出上,然后返回。
为了重现这个问题,我启动了16个loop.bat实例,并让它运行了一整晚。当我早上回来的时候,大约有一半的实例被卡住了。
下面是我使用的代码:Loop.bat
@echo off
:loop
tclsh86 1.tcl
goto loop
tcl 1. puts "start 1.tcl"
set error [catch {eval {exec tclsh86 2.tcl >@stdout 2>@stderr}} results]
puts "error = $error"
puts "results = $results"
puts "end 1.tcl"
return 0
tcl 2. puts stdout "Print to stdout from 2.tcl."
puts stderr "Print to stderr from 2.tcl."
return 1
为了重现这个问题,我启动了16个loop.bat实例,并让它运行了一整晚。当我早上回来的时候,大约有一半的实例被卡住了。
通过'exec', 'puts'地址和批处理循环的迭代创建了新的线程和文件套接字。如果套接字或线程的创建速度快于恢复速度,被调用的子进程最终将耗尽可用的套接字或线程。
这可能有助于解释:https://web.archive.org/web/20190217153445/https://blogs.msdn.microsoft.com/oldnewthing/20050729-14/?p=34773
一个解决方案可能是给Windows更多的进程控制权,并使用start
来执行tclsh86
:
@echo off
:loop
start /b /wait tclsh86 1.tcl
goto loop
这可能解决问题。'/b'禁止每次启动tclsh86
时创建新控制台