运行 tcl 脚本时的后台进程是什么? [英] What is the background process when a tcl script is run?

查看:29
本文介绍了运行 tcl 脚本时的后台进程是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当您启动 tcl 脚本时,发生的后台进程是什么.(类似于c编译)?

When you start a tcl script, what is the background process that happens. ( similar to c compilation )?

当您启动 expect 时,脚本进程如何工作?

When you start the expect, how the script process works?

推荐答案

假设你已经有一个正在运行的 Tcl 解释器,并且只需 source 你的脚本来运行它(这避免了描述整个解释器启动序列和初始化),在任何最近的 (8.x) Tcl 解释器中都会发生以下事情.

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.

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

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).

这会在没有字节码编译的情况下解释顶级脚本,例如脚本被解析,一旦找到命令,就直接执行.这很慢,而且老的 Tcl 7.x 一直在运行.

This interprets the toplevel script without bytecode compilation, e.g. 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.

但是如果一个命令被执行,它会检查该命令是否可以被字节编译成更有效的形式.这是通过 proc 定义的命令的情况,因此如果第一次执行命令,Tcl_EvalObjEx() 在内部调用 TclCompileObj()获取命令的字节码表示,它缓存在解析命令的 Tcl_Obj 中.

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.

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

If the command cannot be compiled, it is executed directly, e.g. 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. This function may also come from some C extension loaded into the interpreter and is treated exactly in the same way. The available commands are registered internally in some hash table, thats what Tcl_CreateObjCmd() does.

但是如果可以编译命令,就会发生一些不同的事情.在这种情况下,命令被转换为字节码表示.例如,对于这样一个简单的过程: proc c {a b} {concat $a $b} 这被转换成四个字节码.你实际上可以通过 ::tcl::unsupported::disassemble 命令检查生成的字节码,看看这个 Tkcon session with a Tcl 8.6.3:

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 {a b} {concat $a $b} this is turned into four bytecodes. 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:

() 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 文件中找到它的实现.

This bytecode (the four lines at the bottom) is executed by a virtual machine inside the Tcl interpreter. It is a stack based VM currently. You can find its implementation inside the generic/tclExecute.c file.

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

Not all commands can be bytecoded yet, if a command has no matching bytecode, a call to the plain function is generated, e.g. one of the Tcl_*ObjCmd things mentioned for direct execution.

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

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 与普通 Tcl 相同,只是通过 Tcl_CreateObjCmd() 添加了一些额外的命令.

Expect is identical to a normal Tcl for this, it just adds a few extra commands via Tcl_CreateObjCmd().

这篇关于运行 tcl 脚本时的后台进程是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆