繁体   English   中英

运行tcl脚本时的后台进程是什么?

[英]What is the background process when a tcl script is run?

启动tcl脚本时,将发生什么后台进程。 (类似于c编译)?

当您启动期望时,脚本过程如何工作?

假设你已经有一个正在运行的Tcl解释,只是source脚本来运行它(以避免描述整个翻译启动序列和初始化),下面的事情发生在任何近期(8.x的)Tcl解释。

这基本上会调用某些C代码,例如Tcl_EvalFile() ,它将脚本加载到内存中,以及实际执行内部内部TclEvalEx() ,这是TclEvalEx()的私有版本, Tcl_EvalEx()处所述( https ://www.tcl.tk/man/tcl/TclLib/Eval.htm )。

这无需字节码编译即可解释顶级脚本,例如,脚本被解析后,一旦找到命令,便会直接执行。 这是相当慢的,并且较老的Tcl 7.x一直都在运行。

但是,如果执行了一条命令,则会检查该命令是否可以字节编译为更有效的形式。 通过proc定义的命令就是这种情况,因此,如果第一次执行命令,则Tcl_EvalObjEx()会在内部调用TclCompileObj()来获取命令的字节码表示形式,该字节码表示形式将缓存在已解析命令的Tcl_Obj内。

如果无法编译该命令,则直接执行该命令,例如,调用generic/tclCmd*.c中的功能之一,例如,要处理命令concat该命令将是generic/tclCmdAH.c Tcl_ConcatObjCmd() 此函数也可能来自加载到解释器中的某些C扩展,并且以完全相同的方式处理。 可用命令在内部在某些哈希表中注册,这就是Tcl_CreateObjCmd()作用。

但是,如果可以编译该命令,则会发生一些不同的事情。 在这种情况下,该命令将转换为字节码表示形式。 例如,对于这样一个简单的过程: proc c {ab} {concat $a $b} ,它将变成四个字节码。 您实际上可以通过::tcl::unsupported::disassemble命令检查生成的字节码,并使用Tcl 8.6.3来查看此Tkcon会话:

() 69 % proc c {a b} {concat $a $b}
() 70 % ::tcl::unsupported::disassemble proc c
ByteCode 0x00000000045A2660, refCt 1, epoch 16, interp 0x0000000002E26120 (epoch 16)
  Source "concat $a $b"
  Cmds 1, src 12, inst 10, litObjs 0, aux 0, stkDepth 2, code/src 0.00
  Proc 0x0000000002EB32A0, refCt 1, args 2, compiled locals 2
      slot 0, scalar, arg, "a"
      slot 1, scalar, arg, "b"
  Commands 1:
      1: pc 0-8, src 0-11
  Command 1: "concat $a $b"
    (0) loadScalar1 %v0     # var "a"
    (2) loadScalar1 %v1     # var "b"
    (4) concatStk 2 
    (9) done 

该字节码(底部的四行)由Tcl解释器内部的虚拟机执行。 当前是基于堆栈的VM。 您可以在generic/tclExecute.c文件中找到其实现。

并非所有命令都可以字节Tcl_*ObjCmd ,如果命令没有匹配的字节码,则会生成对普通函数的调用,例如,提到的直接执行Tcl_*ObjCmd之一。

在大多数情况下(几乎在每次重用命令时)字节码都快得多。 这是建议将所有代码放入过程(它们以这种方式进行字节编译)并支撑表达式的原因之一。

希望这能说明这一过程。 我遗漏了一些更复杂的细节,例如编译时代以及协同例程,非递归引擎等问题。

对此,Expect与普通的Tcl相同,它只是通过Tcl_CreateObjCmd()添加了一些额外的命令。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM