我对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'函数调用没有被触发?
任何人都可以帮助我理解这种行为。
答案 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
,这样做会重新进入事件循环,这被视为不良行为。