关于tcl中命名管道的行为
我有一个关于tcl中命名管道的问题 首先,我使用mkfifo创建了管道:关于tcl中命名管道的行为,tcl,named-pipes,tk,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
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
依赖于eventloop,您不需要输入。fileevent
只是告诉Tcl在可读时调用read\u fifo
如果您想阻止IO,那么只需调用get
。这将阻塞,直到读取整行
set fifo [open "foo" r]
fconfigure $fifo -blocking 1
gets $fifo x
puts "x is $x"
如果使用事件驱动,则需要fileevent
,使用非阻塞IO,并且必须进入事件循环(例如使用vwait forever
)
设置fifo[打开“foo”r]
fconfigure$fifo-阻止0
proc read_fifo{fifo}{
将“调用读取fifo”
如果{[gets$fifo x]<0}{
如果{[eof$fifo]}{
#在这里做些清理。
关闭$fifo
}
}
把“x是$x”
}
fileevent$fifo可读[列表读取\u fifo$fifo]
永远等待#进入eventloop
不要将事件驱动与阻塞IO混合使用。这真的不管用
请注意,您不必在Tk中调用
vwait
,这样做会重新进入事件循环,这被认为是不好的做法。从技术上讲,事件驱动和阻塞IO可以协同工作。只是你经常会对结果不满意。如果你在事件驱动的应用程序中使用阻塞IO,就不会提供任何事件。对于Tk,GUI将变得无响应,eggdrop将获得ping超时。啊,但是wish(在Unix上)以事件驱动的方式使用阻塞IO。它在控制台上是这样做的,因为它假定(通常是正确的!)控制台正在逐行为它生成输入。@DonalFellows这也是我最近在windows上发现的。如果我不包需要Tk;在Tclsh中500{put{Eventloop running}}
之后,它将触发该事件,但不会在不加载Tk的情况下触发。(我只是不知道这是怎么回事。)
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