Upload
kyon-mm
View
621
Download
1
Embed Size (px)
DESCRIPTION
JJUGでGroovyでCSPを使い始めることについて紹介しました。
Citation preview
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は学術目的のみ無償で利用できるライセンスです。
Conclusion
Conclusion
CSPを使ってみたいなら、GParsを使うと簡単なプロセスがいくつか定義されているので、動かしやすいし、Groovy自体の書きやすさもあってよい。
モデルとコードが近くなりやすいCSPで書いておくと、ツールでの検証が捗るし、検証してからコードに書くのもそんなに困らない。
机上デバッグやめたいれす^q^
Append
非同期処理のプロジェクトで失敗したのをキッカケに真面目に取り組み始めました。
いまは、CSPベースの何かを開発しています。
CIサーバ
テスティングフレームワーク
ビルドツール
ご清聴ありがとぴょん◆