Вопрос

Я использую симулятор дискретных событий под названием 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 или в моем коде...

Это было полезно?

Решение

Редактировать:теперь понимание государственной машины

Во-первых, используемый вами синтаксис цитирования может доставить вам неприятности.Как правило, вы должны создавать команды Tcl с использованием list, это гарантирует, что 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}]}

Другие советы

Проблема в том, что вы подставляете значение своих переменных немедленно, а не во время вычисления кода.Вам нужно отложить замену.Таким образом, вместо:

$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 ВОЗВРАТ.

Я не уверен, почему это работает, но это работает:

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

Если кто-нибудь знает объяснение, это было бы здорово.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top