1

我正在使用一个名为 ns-2 的离散事件模拟器,它是使用 Tcl 和 C++ 构建的。我试图在 TCL 中编写一些代码:

set ns [new Simulator]

set state 0

$ns at 0.0 "puts \"At 0.0 value of state is: $state\""
$ns at 1.0 "changeVal"
$ns at 2.0 "puts \"At 2.0 values of state is: $state\""

proc changeVal {} {
    global state
    global ns
    $ns at-now "set state [expr $state+1]"
    puts "Changed value of state to $state"
}

$ns run

这是输出:

At 0.0 value of state is: 0
Changed value of state to 0
At 2.0 values of state is: 0

state 的值似乎没有改变。我不确定我在使用 TCL 时是否做错了什么。任何人都知道这里可能出了什么问题?

编辑:感谢您的帮助。实际上,ns-2 是我无法控制的东西(除非我重新编译模拟器本身)。我尝试了这些建议,这是输出:

对于代码:

set ns [new Simulator]

set state 0

$ns at 0.0 "puts \"At 0.0 value of state is: $state\""
$ns at 1.0 "changeVal"
$ns at 9.0 "puts \"At 2.0 values of state is: $state\""

proc changeVal {} {
    global ns
    set ::state [expr {$::state+1}]
    $ns at-now "puts \"At [$ns now] changed value of state to $::state\""
}

$ns run

输出是:

At 0.0 value of state is: 0
At 1 changed value of state to 1
At 2.0 values of state is: 0

对于代码:

set ns [new Simulator]

set state 0

$ns at 0.0 "puts \"At 0.0 value of state is: $state\""
$ns at 1.0 "changeVal"
$ns at 9.0 "puts \"At 2.0 values of state is: $state\""

proc changeVal {} {
    global ns
    set ::state [expr {$::state+1}]
    $ns at 1.0 {puts "At 1.0 values of state is: $::state"}
}

$ns run

输出是:

At 0.0 value of state is: 0
At 1.0 values of state is: 1
At 2.0 values of state is: 0

似乎不起作用...不确定是ns2还是我的代码有问题...

4

3 回答 3

2

编辑:现在了解状态机

首先,您使用的引用语法会给您带来麻烦。您通常应该使用 list 构建 Tcl 命令,这可以确保Tcl 不会扩展您不希望它扩展的内容。

当您拨打电话时,您的at-now电话正在替换state变量(即当值不变且为 0 时。您想要的是:

$ns at-now 0.0 {puts "At 0.0 value of state is: $::state"}
$ns at-now 2.0 {puts "At 2.0 value of state is: $::state"}

看起来您changeVal的编写正确(第一个版本有一些相同的替换问题),以及您传递将在本地使用的变量引用这一事实,因此没有设置全局状态。

问题第一版的部分解决方案- 使用全局引用,并在调用时引用[$以防止替换:

$ns at-now "set ::state \[expr {\$::state + 1}\]"

或者,使用花括号:

$ns at-now {set ::state [expr {$::state + 1}]}
于 2010-03-29T15:16:47.333 回答
2

问题是您要立即替换变量的值,而不是在评估代码时。您需要推迟替换。因此,而不是:

$ns at 2.0 "puts \"At 2.0 values of state is: $state\""

做这个:

$ns at 2.0 {puts "At 2.0 values of state is: $state"}

在进行这样的调用时,最好将比简单的命令调用更复杂的东西放入过程中而不进行替换,这是一种很好的做法。使其正常工作要容易得多。

[编辑]
此外,at-now仍然推迟执行其主体,直到当前at返回之后。

于 2010-03-29T15:26:32.303 回答
0

我不知道为什么这有效,但它有效:

set ns [new Simulator]

set state 0

proc changeVal {} {
    global ns
    incr ::state
    $ns at-now {puts "Local::At [$ns now] values of state is: $::state"}
}

$ns at 0.0 "puts \"Global::At 0.0 value of state is: $state\""
changeVal
$ns at 9.0 "puts \"Global::At 2.0 values of state is: $state\""

$ns run

输出:

Global::At 0.0 value of state is: 0
Local::At 0 values of state is: 1
Global::At 2.0 values of state is: 1

如果有人知道解释,那就太好了。

于 2010-03-29T16:08:12.053 回答