2

我对 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”函数调用?

谁能帮助我理解这种行为。

4

1 回答 1

3

fileevent依赖于您不输入的事件循环。只是告诉 Tcl在可读时
fileevent调用。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 混为一谈。这真的行不通。

请注意,您不必调用vwaitTk,这样做会重新进入事件循环,这被认为是不好的做法。

于 2013-09-19T11:49:03.453 回答