简体   繁体   English

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

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

When you start a tcl script, what is the background process that happens. 启动tcl脚本时,将发生什么后台进程。 ( similar to c compilation )? (类似于c编译)?

When you start the expect, how the script process works? 当您启动期望时,脚本过程如何工作?

Assuming you already have a running Tcl interpreter and just source your script to run it (which avoids describing the whole interpreter startup sequence and initialization), the following things happen in any recent (8.x) Tcl interpreter. 假设你已经有一个正在运行的Tcl解释,只是source脚本来运行它(以避免描述整个翻译启动序列和初始化),下面的事情发生在任何近期(8.x的)Tcl解释。

This basically invokes some C-Code like Tcl_EvalFile() which loads the script into memory, and hands of the work of actually doing the execution to the internal TclEvalEx() , which is a private version of Tcl_EvalEx() , as documented here ( https://www.tcl.tk/man/tcl/TclLib/Eval.htm ). 这基本上会调用某些C代码,例如Tcl_EvalFile() ,它将脚本加载到内存中,以及实际执行内部内部TclEvalEx() ,这是TclEvalEx()的私有版本, Tcl_EvalEx()处所述( https ://www.tcl.tk/man/tcl/TclLib/Eval.htm )。

This interprets the toplevel script without bytecode compilation, eg the script is parsed, once a command is found, it is executed directly. 这无需字节码编译即可解释顶级脚本,例如,脚本被解析后,一旦找到命令,便会直接执行。 This is quite slow and the way the older Tcl 7.x operated all the time. 这是相当慢的,并且较老的Tcl 7.x一直都在运行。

But if a command is executed, it is checked if the command can be byte-compiled into a more efficient form. 但是,如果执行了一条命令,则会检查该命令是否可以字节编译为更有效的形式。 This is the case for commands defined via proc so if a command gets executed the first time, the Tcl_EvalObjEx() calls TclCompileObj() internally to get a bytecode representation of the command, which is cached inside the Tcl_Obj of the parsed command. 通过proc定义的命令就是这种情况,因此,如果第一次执行命令,则Tcl_EvalObjEx()会在内部调用TclCompileObj()来获取命令的字节码表示形式,该字节码表示形式将缓存在已解析命令的Tcl_Obj内。

If the command cannot be compiled, it is executed directly, eg one of the functions in generic/tclCmd*.c is called, for example to handle the command concat the command would be Tcl_ConcatObjCmd() in generic/tclCmdAH.c . 如果无法编译该命令,则直接执行该命令,例如,调用generic/tclCmd*.c中的功能之一,例如,要处理命令concat该命令将是generic/tclCmdAH.c Tcl_ConcatObjCmd() This function may also come from some C extension loaded into the interpreter and is treated exactly in the same way. 此函数也可能来自加载到解释器中的某些C扩展,并且以完全相同的方式处理。 The available commands are registered internally in some hash table, thats what Tcl_CreateObjCmd() does. 可用命令在内部在某些哈希表中注册,这就是Tcl_CreateObjCmd()作用。

But if the command can be compiled, something different happens. 但是,如果可以编译该命令,则会发生一些不同的事情。 In that case, the command is turned into a bytecode representation. 在这种情况下,该命令将转换为字节码表示形式。 For example for a trivial procedure like this: proc c {ab} {concat $a $b} this is turned into four bytecodes. 例如,对于这样一个简单的过程: proc c {ab} {concat $a $b} ,它将变成四个字节码。 You can actually inspect the generated bytecode via the ::tcl::unsupported::disassemble command, have a look at this Tkcon session with a Tcl 8.6.3: 您实际上可以通过::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 

This bytecode (the four lines at the bottom) is executed by a virtual machine inside the Tcl interpreter. 该字节码(底部的四行)由Tcl解释器内部的虚拟机执行。 It is a stack based VM currently. 当前是基于堆栈的VM。 You can find its implementation inside the generic/tclExecute.c file. 您可以在generic/tclExecute.c文件中找到其实现。

Not all commands can be bytecoded yet, if a command has no matching bytecode, a call to the plain function is generated, eg one of the Tcl_*ObjCmd things mentioned for direct execution. 并非所有命令都可以字节Tcl_*ObjCmd ,如果命令没有匹配的字节码,则会生成对普通函数的调用,例如,提到的直接执行Tcl_*ObjCmd之一。

Bytecodes are much faster for most cases (nearly every time a command is reused). 在大多数情况下(几乎在每次重用命令时)字节码都快得多。 That is one reason for the advices to put all your code inside procedures (they get byte-compiled that way), and to brace your expressions. 这是建议将所有代码放入过程(它们以这种方式进行字节编译)并支撑表达式的原因之一。

Hope this illustrates the process a bit. 希望这能说明这一过程。 I left out a few more complex details like compile epoches and the problems of co-routines, non-recursive engine etc. 我遗漏了一些更复杂的细节,例如编译时代以及协同例程,非递归引擎等问题。

Expect is identical to a normal Tcl for this, it just adds a few extra commands via Tcl_CreateObjCmd() . 对此,Expect与普通的Tcl相同,它只是通过Tcl_CreateObjCmd()添加了一些额外的命令。

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

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