Groovyで学ぶプロセス代数 #jjug

Post on 28-Nov-2014

625 views 1 download

description

JJUGでGroovyでCSPを使い始めることについて紹介しました。

Transcript of Groovyで学ぶプロセス代数 #jjug

Learning Process Calculate with CSP, Groovy, GPars

in JJUG 2014.09.18 kyon_mm

Self Introduction

きょん kyon_mm

テストアーキテクト 2年目

TDD/BDD, SCM, Agile, Softwaretest, SoftwareEngineering

なごや

基礎勉強会, SCMBC, Nagoya.Testing, Cafe.Testing

Agenda

the word of CSP

Good points

Try! GPars! Verify! FDR!

the word of CSP

CSP

並行処理のモデルとして利用されているプロセス代数の一例です。

プロセス代数の他の例としては、ご存知π計算だと思います。

太一(@ryushi)さんが名古屋に来たときにGoの話をしていたので、jjugの皆様もGoを知っていると思い、Goユーザには身近なCSPの話をしにきました。

CSP

Tony Hoareが考案したモデルで、いまや様々な言語やフレームワークに影響を与えています。Occamはもちろんですが、Erlangも影響を受けています。

並行処理関連で「チャネル」がうんたらとか言われたら、CSPかな?って思って聞くといいかもだよ!

Good points

Good points

研究者と実績がたくさん

逐次実行と並行実行の仕様を比較するツール

Groovy(もしくはJava)で実装できる

逐次実行と並行実行 の比較

並行実行を正しく仕様化するのは難しいと言われており、僕もよく間違います。

逐次実行だったらあまり間違わないところでも、並行実行にするだけで難しくなることがよくある。

逐次実行と並行実行 の比較

そこで、FDR(ツール)ですよ。CSPとほぼ同等の記法のスクリプトを入力とする検証ツール。

CSP記法で同じ結果を得るための「逐次実行の仕様」と「並行実行の仕様」両方を書く。

FDRにそれぞれを入力すると、どの程度同一か判定してくれる!

結果によっては、ライブロックフリー、デッドロックフリーなどが保証される!!

Groovyで書ける

CSPをJava実装したものがJCSPというライブラリとして後悔されていて、GParsはJCSPをラップしている!

Groovyに並行処理を書ける!

Try GPars

GPars

Groovyをインストールすれば入っています。

org.codehaus.gpars:gpars:1.2.1

JCSPスタイルで書く事も、GParsスタイルで書く事も可能。

GParsスタイル = DataFlowクラス系との組み合わせ

Sample

groovyx.gpars.plugAndPlayパッケージ配下に簡単なものがいくつか定義されているので、それらを使って、とりあえず動かしてみる事ができます

plugAndPlay classes

GConsole

GConsoleStringToInteger

GDelta2

GFixedDelay

GIdentity

GIntegrate

GNumbers

GObjectToConsoleString

GPairs

GParPrint

GPCopy

GPlus

GPrefix

GPrint

GSquares

GStatePairs

GSuccessor

GTail

class Executor implements CSProcess {

def out1

def out2

def random = new Random()

@Override

void run() {

while (true){

out1.write(random.nextInt() % 10)

out2.write(random.nextInt() % 10)

sleep(50L)

}

}

}

def channelA = Channel.one2one()

def channelB = Channel.one2one()

def channelC = Channel.one2one()

final def par = new PAR([

new Executor(out1: channelA.out(), out2: channelB.out()),

new GPlus(inChannel0: channelA.in(), inChannel1:channelB.in(), outChannel: channelC.out()),

new GPrint(inChannel: channelC.in(), heading: "足し算しちゃうよ?")

])

par.run()

JCSP,GPars

処理はCSProcessインターフェースの実装に書きます。これをプロセスといいます。

プロセスとプロセスのやり取りはチャネルを通してのみ行います。

1プロセス対Nプロセス、1チャネル対Nチャネルもあります。

JCSP,GPars

new PAR([someProcess,,,])とすることで、プロセス合成をしている。

制限がありますが、プロセス通信は1マシン内でも、マシン間でも出来ます。(夢がひろがる!

例えばGSuccessorのなかみ↓

ChannelInput inChannel

ChannelOutput outChannel

void run() {

while (true) {

outChannel.write(inChannel.read() + 1)

}

}

例えばGPrintのなかみ↓

ChannelInput inChannel

String heading = "No Heading Provided"

long delay = 200

def void run() {

def timer = new CSTimer()

println "${heading}"

while (true) {

println inChannel.read().toString()

if (delay != 0) {

timer.sleep(delay)

CSP

チャネルは同期的に動作し、プロセスは非同期に動作する。(同期的メッセージング、非同期動作)

ただし、GParsではチャネルを非同期にすることもできる!(実際あやうい気はするが、わからない)

Sample with Dataflow

入力した文字列をフォーマットして、挨拶文を返すプログラム

Input <-> Formatter <-> Greeter <-> Output

class Formatter implements Callable<String> {

DataflowReadChannel rawNames

DataflowWriteChannel formattedNames

@Override

String call() {

while(!Thread.currentThread().isInterrupted()) {

String name = rawNames.val

formattedNames << name.toUpperCase()

}

}

}

class Greeter implements Callable<String> {

DataflowReadChannel names

DataflowWriteChannel greetings

@Override

String call() {

while(!Thread.currentThread().isInterrupted()) {

String name = names.val

greetings << "Hello " + name

}

}

}

def a = new SyncDataflowQueue()

def b = new SyncDataflowQueue()

def c = new SyncDataflowQueue()

!

group.task new Formatter(rawNames:a, formattedNames:b)

group.task new Greeter(names:b, greetings:c)

!

// 送信と受信をする

a << “Joe" // チャネルに送信

println c.val // 出力

Verify FDR

FDR3 Released!

書籍やなんかではFDR2!と書かれていますが、現在はFDR3.10がリリースされています。

FDRは学術目的のみ無償で利用できるライセンスです。

FDR3

みてみよう!

http://www.cs.ox.ac.uk/projects/fdr/

FDR3 で 検索!

Conclusion

Conclusion

CSPを使ってみたいなら、GParsを使うと簡単なプロセスがいくつか定義されているので、動かしやすいし、Groovy自体の書きやすさもあってよい。

モデルとコードが近くなりやすいCSPで書いておくと、ツールでの検証が捗るし、検証してからコードに書くのもそんなに困らない。

机上デバッグやめたいれす^q^

Append

非同期処理のプロジェクトで失敗したのをキッカケに真面目に取り組み始めました。

いまは、CSPベースの何かを開発しています。

CIサーバ

テスティングフレームワーク

ビルドツール

ご清聴ありがとぴょん◆