的Tcl不能同時做幾件事情,尤其是當它本身將是I/O密集型的,而這樣做的等待。爲此,我們需要利用eggdrop(我認識到bind
類型)正在運行事件循環的事實,並使用fileevent
命令。 fileevent
命令非常棒,因爲它可以讓我們安排某些代碼在某個通道上發生「某些事情」時運行;當通道是管道(或插座)時,可以使用可讀的事件來執行某些文本讀取或通道關閉時的操作。 (除非你真的讀了一些東西,否則很難區分。)
讓我們把這些東西放在一起:管道和報告結果的背面。我出示asyncpipe
命令!
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
}
}
好的,這是建立基本的機械,但它還不是特別清楚。以下是如何使用它。
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輸出。 (寫一個使用解壓縮代碼的「副本」只是一個練習;它是一個完全剪切-n粘貼的工作,除了解壓縮的參數之外)。異步編程是比您習慣的複雜一點,但只要您使用命名的回調函數進行回調,您就可以工作而不會感到困惑。
忽略機器,專注於更高層次上發生的事情。重寫的unrar
解析其參數,並要求unrar
以子進程的形式異步運行。只要有輸出,它就會被觸發到unrar.report
(一次一行),並將它寫入日誌。您可能想要在其他地方報告,而不是/以及。當管道結束時,unrar.done
被調用,因此它可以記錄它已完成。我將名稱傳入unrar.report
和unrar.done
,因爲可以看到什麼已完成;知道發生了什麼偶爾是異步程序的問題,所以它確實有幫助。 (這是一個明確的提示!)
你可以一次啓動任何次數的事情。做了太多(有多少取決於你的硬件),你的電腦會放慢速度,可能很多,但它最終會趕上。
解壓到哪裏?不會出現在您的代碼中。 –
我已經在$ name .rar和.zip文件中,並且用unrar解壓這個,問題不在於rar或zip,同時是我的問題,關於 –