tclshell运行linux脚本,shell – 从TCL脚本和格式化输出在后台运行命令

如果命令没有相互依赖的状态,则可以将它们并行化.有很多方法可以做到这一点,但其中一个更容易的是使用线程包的

thread pooling(这需要一个线程Tcl,现在许多平台上的标准):

package require Thread

set pool [tpool::create -maxworkers 4]

# The list of *scripts* to evaluate

set tasks {

{command 1}

{command 2}

...

{command n}

}

# Post the work items (scripts to run)

foreach task $tasks {

lappend jobs [tpool::post $pool $task]

}

# Wait for all the jobs to finish

for {set running $jobs} {[llength $running]} {} {

tpool::wait $pool $running running

}

# Get the results; you might want a different way to print the results...

foreach task $tasks job $jobs {

set jobResult [tpool::get $pool $job]

puts "TASK: $task"

puts "RESULT: $jobResult"

}

主要的tweakable是线程池的大小,默认为4的限制.(通过-maxworkers选项将它设置为tpool :: create,我已在上面明确列出.)选择的最佳值取决于有多少您拥有的CPU核心以及每个任务平均产生的CPU负载量;你需要测量和调整……

您还可以使用-initcmd选项使用您选择的脚本预加载池中的每个工作线程.这是一个放置您的包需要电话的好地方.工人们完全独立于主线和主线;他们不分享国家.如果你在一个单独的进程中运行每一段代码,你会得到相同的模型(但是你最终会编写更多的代码来进行协调).

[编辑]:这是一个适用于Tcl 8.4并使用子进程的版本.

namespace eval background {}

proc background::task {script callback} {

set f [open |[list [info nameofexecutable]] "r+"]

fconfigure $f -buffering line

puts $f [list set script $script]

puts $f {fconfigure stdout -buffering line}

puts $f {puts [list [catch $script msg] $msg]; exit}

fileevent $f readable [list background::handle $f $script $callback]

}

proc background::handle {f script callback} {

foreach {code msg} [read $f] break

catch {close $f}

uplevel "#0" $callback [list $script $code $msg]

}

proc accumulate {script code msg} {

puts "#### COMMANDS\n$script"

puts "#### CODE\n$code"

puts "#### RESULT\n$msg"

# Some simple code to collect the results

if {[llength [lappend ::accumulator $msg]] == 3} {

set ::done yes

}

}

foreach task {

{after 1000;subst hi1}

{after 2000;subst hi2}

{after 3000;subst hi3}

} {

background::task $task accumulate

}

puts "WAITING FOR TASKS..."

vwait done

注意:任务是生成结果的Tcl命令,但它们不能打印出结果;结构代码(在background :: task中)处理它.这些是子过程;它们彼此之间没有任何共享,因此您希望它们执行或配置的任何内容都必须作为任务的一部分发送.一个更复杂的版本可以保持一个热的子进程池,并且通常非常像一个线程池(由于在子进程而不是一个线程中的细微差别),但这比我想在这里编写的代码更多.

结果代码(即异常代码)对于“ok”为0,对于“错误”为1,在不常见的情况下为其他值.它们正是070​​01中记录的值;由你来正确解释它们. (我想我还应该添加代码,以便在出现错误的情况下报告:: errorInfo和:: errorCode变量内容,但这会使代码更加复杂……)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值