tcl - 关于 tcl 中的命名管道行为

标签 tcl named-pipes tk-toolkit

我有一个关于 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/

相关文章:

bash - 如何让 tclsh 忽略 EOF?

arrays - 重命名全局数组 TCL

java - 在 Java 中创建命名管道

mysql - 命名 fifo 管道是否使用磁盘写入和读取?

python - tkFileDialog 不将结果转换为 Windows 上的 Python 列表

linux - 如何判断远程 tty 是否正在等待输入?

tcl - 为什么 expr $a eq $b 失败并显示 "invalid bareword"?

shell - 如何使用 tcl-expect 等待进程完成

c++ - 每次我在 linux c++ 中运行命名管道程序时都会发出 SIGSTOP 信号

python - 为什么 Python 发行版中的所有 tk 示例都是用 TCL 编写的?