次のプログラム例では、DTrace の profile プロバイダを使って、単純な時間ベースのカウンタを実装します。profile プロバイダは、D プログラム内の記述に基づいて新しいプローブを作成できます。たとえば、profile:::tick-nsec (n は整数) という名前のプローブを作成した場合、profile プロバイダは、n 秒ごとに起動するプローブを 1 つ作成します。次のソースコードを記述し、counter.d という名前のファイルに保存します。
/* * Count off and report the number of seconds elapsed */ dtrace:::BEGIN { i = 0; } profile:::tick-1sec { i = i + 1; trace(i); } dtrace:::END { trace(i); }
実行すると、Control-C キーを押すまでの経過秒数がカウントされ、最後に合計が出力されます。
# dtrace -s counter.d dtrace: script 'counter.d' matched 3 probes CPU ID FUNCTION:NAME 0 25499 :tick-1sec 1 0 25499 :tick-1sec 2 0 25499 :tick-1sec 3 0 25499 :tick-1sec 4 0 25499 :tick-1sec 5 0 25499 :tick-1sec 6 ^C 0 2 :END 6 # |
プログラムの最初の 3 行は、プログラムの内容を説明するコメント行です。C、C++、および Java プログラミング言語の場合と同様に、D コンパイラは /* と */ で囲まれた文字列をすべて無視します。コメントは、D プログラム内のどこでも使用できます。プローブ節の中でも外でも使用できます。
BEGIN プローブ節では、次の文により、i という名前の新しい変数が定義され、整数値 0 が割り当てられています。
i = 0;
C、C++、および Java プログラミング言語の場合とは異なり、D の変数は、プログラム文の中で使用するだけで作成されます。明示的変数宣言は不要です。変数の型は、この変数をプログラム内ではじめて使用したとき、そこに代入された値の型になります。各変数は 1 つの型を持ち、プログラムの完了時まで変わりません。したがって、2 回目以降の使用時にも、最初に代入された値と同じ型の値を参照させる必要があります。たとえば、counter.d の変数 i に最初に代入される値は、整数定数 0 です。そのため、この変数の型は int になります。D は、C と同じ基本的な整数データ型を提供します。たとえば、次のデータ型があります。
char |
文字型または単一バイトの整数型 |
int |
デフォルト整数型 |
short |
短整数型 |
long |
長整数型 |
long long |
拡張された長整数型 |
これらのデータ型のサイズは、オペレーティングシステムカーネルのデータモデル (第 2 章型、演算子、および式を参照) によって異なります。また D では、オペレーティングシステムごとに定義されている各種データ型と同様に、さまざまな固定長の符号付き/符号なし整数型に、覚えやすい組み込み名が付けられています。
counter.d の中央部分には、カウンタ i の値を増分するプローブ節があります。
profile:::tick-1sec { i = i + 1; trace(i); }
この節には、使用可能なプロセッサ上で毎秒 1 回起動する新しいプローブを作成するように profile プロバイダに指示する、profile:::tick-1sec という名前のプローブが指定されています。この節に含まれる 2 つの文のうち、最初の文は以前の値に 1 を加算して i に代入し、2 番目の文は新しい i の値をトレースします。D では、C の一般的な算術演算子をすべて使用できます。使用可能な算術円算子のリストは、第 2 章型、演算子、および式に記載されています。また C の場合と同様に、++ 演算子は、対応する変数を 1 増分したい場合に使用します。trace() 関数は、引数として任意の D 式を取ります。この考えに従って counter.d をさらに簡潔に書き直すと、次のようになります。
profile:::tick-1sec { trace(++i); }
変数 i の型を明示的に制御したい場合は、型名を丸括弧で囲んで割り当てます。こうすれば、整数 0 がその型に「キャスト」されます。たとえば、D で char の最大サイズを決定したい場合は、BEGIN 節を次のように変更します。
dtrace:::BEGIN { i = (char)0; }
counter.d の実行を開始してしばらくすると、トレース値が大きくなり、その後再びゼロに戻ります。値がゼロに戻るのを待てない場合は、profile プローブ名を profile:::tick-100msec に変更してみてください。こうすれば、カウンタの値は 100 ミリ秒に 1 回 (毎秒 10 回) のペースで増分するようになります。