关于tcl中的命名管道行为

时间:2013-09-19 11:43:45

标签: tcl named-pipes tk

我对tcl中的命名管道有疑问。

首先我用mkfifo创建了管道:

mkfifo foo 

然后执行以下tcl脚本:

set fifo [open "foo" r] 
fconfigure $fifo -blocking 1 
proc read_fifo {} { 
    global fifo 
    puts "calling read_fifo" 
    gets $fifo x 
    puts "x is $x" 
} 
puts "before file event" 
fileevent $fifo readable read_fifo 
puts "after file event" 

当我运行tcl脚本时,它会等待一个事件而不输出任何内容。

然后,当我写信给fifo时:

echo "hello" > foo

现在,tcl脚本打印出来:

before file event 
after file event 

为什么'read_fifo'函数调用没有被触发?

任何人都可以帮助我理解这种行为。

1 个答案:

答案 0 :(得分:3)

fileevent依赖于您不能进入的eventloop fileevent只是告诉Tcl在可读时调用read_fifo

如果您想阻止IO,请致电gets。这将阻塞,直到读完整行。

set fifo [open "foo" r] 
fconfigure $fifo -blocking 1 
gets $fifo x 
puts "x is $x"

如果您使用事件驱动,则需要fileevent,使用非阻止IO,您必须输入事件循环(例如使用vwait forever)。

set fifo [open "foo" r] 
fconfigure $fifo -blocking 0 
proc read_fifo {fifo} { 
    puts "calling read_fifo" 
    if {[gets $fifo x] < 0} {
        if {[eof $fifo]} {
           # Do some cleanup here.
           close $fifo
        }
    }
    puts "x is $x" 
} 
fileevent $fifo readable [list read_fifo $fifo]
vwait forever; #enter the eventloop

不要将事件驱动与阻塞IO混合在一起。这不起作用。

请注意,您不必在Tk中调用vwait,这样做会重新进入事件循环,这被视为不良行为。