1

TclとC++を使用して構築されたns-2と呼ばれる離散イベントシミュレーターを使用しています。私は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

状態の値は変わらないようです。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 に答える