我有一个关于 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”函数调用?
任何人都可以帮助我理解这种行为。
最佳答案
fileevent
依赖于事件循环,您无需输入该事件循环。
fileevent
只是告诉 Tcl 在可读时调用 read_fifo
。
如果你想阻塞IO,那么只需调用gets
。这会阻塞,直到读取整行为止。
set fifo [open "foo" r]
fconfigure $fifo -blocking 1
gets $fifo x
puts "x is $x"
如果您采用事件驱动方式,则需要fileevent
,使用非阻塞IO,并且必须进入事件循环(例如使用vwaitforever
)。
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
,这样做会重新进入事件循环,这被认为是不好的做法。
关于tcl - 关于 tcl 中的命名管道行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18893710/