write ahead log

ロールフォワード用

Graphvizの使い方を例題で覚える

Graphvizとは

GraphvizはDot言語という記法で書かれたテキストファイルをグラフ図に変換するツールです.
とりあえずwikipediaを.

AT&Tが開発し,公開しています.

環境作成

コマンドラインからがお好みの方は

# mac
$brew install graphviz

# ubuntu
$sudo aptitude install graphviz

私は面倒なのでChrome拡張を作って使っています.
Dot Lang Viewer
会社支給はWindowsなのでコマンドラインとはいささか相性が悪いのです.(msys2入れてますけどね)

ためす

さて,早速試してみましょう.
お好みのテキストファイルを開いて以下を記述してください. ファイル名はsample.txtとしましょう.

graph sample {
  ジャンプ -- 友情;
  ジャンプ -- 努力;
  ジャンプ -- 勝利;
}

コマンドで試す場合は

$ dot -Tgif sample1.dot -o sample1.gif

Dot Lang Viewerを使う場合は新しいタブを開いてそこへドラッグ&ドロップしてください.
(表示されない場合は設定->その他のツール->拡張機能->DotLangViewerの項の「ファイルのURLへのアクセスを許可する」にチェックを入れてください)

以下の様に表示されます.

上記くらいだと対して恩恵を感じないかもしれません.
でも,以下を作ると考えるとどうでしょう?

多少はありがたみが出るかと思います.

もうちょいためす

もうちょっと実用的っぽい例にしましょう.

μItronの状態遷移図の簡易版を作ってみます.

μItronのマルチタスクは

  • 実行可能状態(Ready)
  • 実行状態(Run)
  • 待ち状態(Wait)

の3つを持ちます.(ほんとはもっとありますが...)

遷移は

  • ReadyからはディスパッチによりRunへ
  • Runからは
    • プリエンプトでReadyへ行く
    • 待ち条件でWaitへ行く
  • Waitからは待ち解除でReadyへ行く

の4つがあります.それぞれシステムコールで変わります.

Dot言語で図にしてみましょう.

まずは3つの状態を表示します.

digraph itron_task {
  実行可能状態;
  実行状態;
  待ち状態;
}

表示してみると以下の様な感じです.

この丸1つずつをnodeと呼びます.(そのままですね)

1つ前のサンプルと異なり,

  • graph(無向グラフ)

ではなく

  • digraph(有向グラフ)

と指定しているのに気付かれたでしょうか.
今回は状態遷移図で矢印が欲しい(有向グラフ)のでdigraphを指定します.

ReadyやWaitなどの説明もほしいですね.
Labelをつけましょう.

digraph itron_task {
  実行可能状態[label="実行可能状態\n(Ready)"];
  実行状態[label="実行状態\n(Run)"];
  待ち状態[label="待ち状態\n(Wait)"];
}

Labelをnode定義の後ろに記述するとnodeの表示名になります.
\nを入れると改行できます.(C言語なんかと一緒です)

次はノードをつなげ合わせましょう.

遷移は

  • ReadyからはディスパッチによりRunへ
  • Runからは
    • プリエンプトでReadyへ行く
    • 待ち条件でWaitへ行く
  • Waitからは待ち解除でReadyへ行く

の4つがありました.

digraph itron_task {
  実行可能状態[label="実行可能状態\n(Ready)"];
  実行状態[label="実行状態\n(Run)"];
  待ち状態[label="待ち状態\n(Wait)"];

  実行可能状態 -> 実行状態;
  実行状態 -> 実行可能状態;
  実行状態 -> 待ち状態;
  待ち状態 -> 実行可能状態;
}

これで以下の様に表示されます.

状態遷移図っぽくなってきました.

状態を変える条件をラベルに入れていきます.

digraph itron_task {
  実行可能状態[label="実行可能状態\n(Ready)"];
  実行状態[label="実行状態\n(Run)"];
  待ち状態[label="待ち状態\n(Wait)"];

  実行可能状態 -> 実行状態[label="ディスパッチ"];
  実行状態 -> 実行可能状態[label="プリエンプト"];
  実行状態 -> 待ち状態[label="待ち条件"];
  待ち状態 -> 実行可能状態[label="待ち解除"];
}

これで内容的には状態遷移図になりました.

最後に状態遷移図っぽい丸にしましょう.
色も少し変えてみます.

digraph itron_task {
  node[shape="doublecircle", style="filled", color="black", fillcolor="aqua"];
  実行可能状態[label="実行可能状態\n(Ready)"];
  実行状態[label="実行状態\n(Run)"];
  待ち状態[label="待ち状態\n(Wait)"];

  実行可能状態 -> 実行状態[label="ディスパッチ"];
  実行状態 -> 実行可能状態[label="プリエンプト"];
  実行状態 -> 待ち状態[label="待ち条件"];
  待ち状態 -> 実行可能状態[label="待ち解除"];
}

それぞれの状態を別の色にもできます.

digraph itron_task {
  node[shape="doublecircle", style="filled", color="black"];
  実行可能状態[label="実行可能状態\n(Ready)", fillcolor="aqua"];
  実行状態[label="実行状態\n(Run)", fillcolor="green"];
  待ち状態[label="待ち状態\n(Wait)", fillcolor="red"];

  実行可能状態 -> 実行状態[label="ディスパッチ"];
  実行状態 -> 実行可能状態[label="プリエンプト"];
  実行状態 -> 待ち状態[label="待ち条件"];
  待ち状態 -> 実行可能状態[label="待ち解除"];
}

これで状態遷移図ができました.

それぞれの丸(ノード)の位置が気になったりするかと思いますが, そこまで制御するのはなかなかしんどいです.(ある程度できるのですが)

Graphviz, Dot Lang ViewerどちらでもSVG出力機能があるので, SVG出力してからInkscapeなどのドローソフトで位置調整するのが無難かなと思います. (私も必要な時はそうしています)