首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >同时解压和解压

同时解压和解压
EN

Stack Overflow用户
提问于 2016-09-17 22:10:07
回答 1查看 188关注 0票数 0

我有一个tcl脚本,但它一次只能解压缩一件事。我现在必须等待它完成的那一刻,然后我才能做下一个。我如何同时做两件事?

代码语言:javascript
复制
bind pubm - "*complete*" unrar

proc unrar {nick host handle channel text} {
    set text [stripcodes bcru $text]
    set name [lindex [split $text] 2];
    set dir "/tmp/unrar"
    if {[catch {exec /bin/sh -c "unrar e $dir/$name $dir/archive/$name"} error]} {
        putlog "error: $error";
    }
}

问候

EN

回答 1

Stack Overflow用户

发布于 2016-09-17 23:55:04

Tcl可以一次做几件事,特别是当它本身在等待时会受到I/O限制的时候。为此,我们需要利用eggdrop (我认识这种类型的bind)正在运行事件循环这一事实,并使用fileevent命令。fileevent命令很棒,因为它可以让我们在通道上“发生一些事情”时安排一些代码运行;当通道是管道(或套接字)时,当有一些文本要读取或通道关闭时,可以使用readable事件来做一些事情。(在你真正读到一些东西之前,很难区分它们。)

让我们把这些部分放在一起:管道和返回结果报告。我将展示asyncpipe命令!

代码语言:javascript
复制
proc asyncpipe {command lineCallback closedCallback} {
    set f [open |$command "r"]
    fileevent $f readable [list asyncpipe.callback $f $lineCallback $closedCallback]
    # There's no output from this command directly, and it returns nearly instantly if your pipeline is sensible.
}
proc asyncpipe.callback {channel lineCallback closedCallback} {
    if {[gets $channel line] >= 0} {
        uplevel "#0" $lineCallback [list $line]
    } elseif {[eof $channel]} {
        catch {close $channel}
        uplevel "#0" $closedCallback
    }
}

好了,这是建立基本的机器,但它还不是特别清楚。下面是如何使用它。

代码语言:javascript
复制
bind pubm - "*complete*" unrar

proc unrar {nick host handle channel text} {
    set text [stripcodes bcru $text]
    set name [lindex [split $text] 2];
    set dir "/tmp/unrar"
    asyncpipe [list unrar e $dir/$name $dir/archive/$name] \
        [list unrar.report putlog $name] [list unrar.done $name]
}
proc unrar.report {name line} {
    putlog "unrar $name :>> $line"
}
proc unrar.done {name} {
    putlog "all done with unrar $name"
}

这将在发生时报告unrar的输出,并允许您一次运行两个。(编写一个使用unzip的“copy”作为练习;除了可能的unzip参数之外,这完全是一个“剪切粘贴”的工作。)异步编程比您习惯的要复杂一些,但是只要您对回调使用命名过程,您就可以工作而不会太困惑。

忽略机器,专注于更高层次上正在发生的事情。重写的unrar解析其参数,并要求unrar作为子进程异步运行。只要有输出,它就会被触发到unrar.report中(一次一行),它会将输出写入日志。您可能希望在其他地方报告它,而不是。当管道结束时,会调用unrar.done,这样它就可以记录它已经完成了。我将名称传递给unrar.reportunrar.done,因为这样就可以看到完成了什么;知道发生了什么在异步程序中偶尔会有问题,所以它有助于准确。(这是一个明确的建议!)

你可以一次启动任何你想要的东西。做太多(多少取决于你的硬件),你的计算机会变慢,可能会很慢,但它最终会赶上。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39547751

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档