-
- [1]
並行単位
- 投稿者:SHIRAISHI Kazuo
- 投稿日:2017年 4月29日(土)18時19分45秒
-
-
実時間プログラムは,いくつかの並行単位と外部手続きで構成されます。
並行単位の1個は,PARACT行で始まりEND PARACT行で終わります。
PARACT行にはその並行単位の名前を書きます。
プログラムを起動すると,一番最初の並行単位が実行を開始します。
他の並行単位はSTART文で起動します。
例
PARACT p1
START p2
FOR i=1 TO 1000
PRINT i
NEXT i
END PARACT
PARACT p2
FOR i=1001 TO 2000
PRINT i
NEXT i
END PARACT
-
- [2]
外部手続き
- 投稿者:SHIRAISHI Kazuo
- 投稿日:2017年 4月29日(土)18時26分40秒
-
-
並行単位を並べた後に外部手続きを書くことができます。
例
PARACT p1
DECLARE NUMERIC x
DECLARE EXTERNAL FUNCTION f
START p2
FOR x=1 TO 1000
PRINT x,f(x)
NEXT x
END PARACT
PARACT p2
DECLARE NUMERIC x
DECLARE EXTERNAL FUNCTION f
FOR x=1001 TO 2000
PRINT x,f(x)
NEXT x
END PARACT
EXTERNAL FUNCTION f(x)
LET f=SQR(x)
END FUNCTION
-
- [3]
外部副プログラム使用例
- 投稿者:SHIRAISHI Kazuo
- 投稿日:2017年 4月29日(土)18時30分42秒
-
-
外部副プログラムの使用例です。
PARACT p1
DECLARE NUMERIC x
DECLARE EXTERNAL SUB s
START p2
FOR x=1 TO 1000
CALL s(x)
NEXT x
END PARACT
PARACT p2
DECLARE NUMERIC x
DECLARE EXTERNAL sub s
FOR x=1001 TO 2000
CALL s(x)
NEXT x
END PARACT
EXTERNAL SUB s(x)
PRINT x,SQR(x)
END SUB
-
- [4]
共用域
- 投稿者:SHIRAISHI Kazuo
- 投稿日:2017年 4月29日(土)19時13分56秒
-
-
並行単位はプログラム単位です。
したがって,異なる並行単位においては同名の変数も異なる変数です。
共用域を宣言することで,各並行単位で共用する変数が確保されます。
共用域の変数には配列を用いることもできます。
共用域を用いる場合には,まず,DECLARE STRUCTURE文で型名を宣言します。
ついで,DECLARE SHARED文で共用域の名称と型を宣言します。
共用域に書き込むのにPUT TO文を用います。
共用域から読み込むのにGET FROM文を用います。
例
DECLARE STRUCTURE struct1 :3 OF NUMERIC
DECLARE SHARED share0 OF struct1
PARACT p1
LET a=1
LET b=2
LET c=3
PUT TO share0 FROM a,b,c
START p2
START p3
START p4
END PARACT
PARACT p2
GET FROM share0 TO a,b,c
LET a=A^2
LET B=B^2
LET C=c^2
PRINT A,B,C
END PARACT
PARACT p3
GET FROM share0 TO a,b,c
LET a=A^3
LET B=B^3
LET C=c^3
PRINT A,B,C
END PARACT
PARACT p4
GET FROM share0 TO a,b,c
LET a=A^4
LET B=B^4
LET C=c^4
PRINT A,B,C
END PARACT
-
- [5]
PUT TO と GET FROM
- 投稿者:SHIRAISHI Kazuo
- 投稿日:2017年 4月29日(土)20時27分13秒
-
-
PUT TO文のFROM句には数値式を書くこともできます。
例
DECLARE STRUCTURE struct1 :3 OF NUMERIC
DECLARE SHARED share0 OF struct1
PARACT p1
LET a=1
LET b=2
LET c=3
PUT TO share0 FROM a^2,b^2,c^2
START p2
PUT TO share0 FROM a^3,b^3,c^3
START p3
PUT TO share0 FROM a^4,b^4,c^4
START p4
END PARACT
PARACT p2
GET FROM share0 TO a,b,c
PRINT A,B,C
END PARACT
PARACT p3
GET FROM share0 TO a,b,c
PRINT A,B,C
END PARACT
PARACT p4
GET FROM share0 TO a,b,c
PRINT A,B,C
END PARACT
このプログラムは,文法上,正しいプログラムですが,
p2に a^2,b^2,c^2
p3に a^3,b^3,c^3
p4に a^4,b^4,c^4
が渡されると考えてはいけません。
p2が実際に走り始めてGET文を実行したときには,share0の値は変化しているかもしれません。
実際の実行結果は,
1 16 81
1 16 81
1 16 81
です。しかし,どのPCでも同じ結果が得られるとはかぎりません。
-
- [6]
PUT TOとGET FROM
- 投稿者:SHIRAISHI Kazuo
- 投稿日:2017年 4月29日(土)20時31分45秒
-
-
共用域を複数用意して使い分ければ,上述の問題は回避できます。
例
DECLARE STRUCTURE struct1 :3 OF NUMERIC
DECLARE SHARED share1 OF struct1
DECLARE SHARED share2 OF struct1
DECLARE SHARED share3 OF struct1
PARACT p1
LET a=1
LET b=2
LET c=3
PUT TO share1 FROM a^2,b^2,c^2
PUT TO share2 FROM a^3,b^3,c^3
PUT TO share3 FROM a^4,b^4,c^4
START p2
START p3
START p4
END PARACT
PARACT p2
GET FROM share1 TO a,b,c
PRINT A,B,C
END PARACT
PARACT p3
GET FROM share2 TO a,b,c
PRINT A,B,C
END PARACT
PARACT p4
GET FROM share3 TO a,b,c
PRINT A,B,C
END PARACT
-
- [7]
共用域の初期値
- 投稿者:SHIRAISHI Kazuo
- 投稿日:2017年 4月29日(土)20時42分3秒
-
-
共用域の初期値は0です。
次のプログラムの実行結果は,
1 2 3
になるか
0 0 0
になるか,予測不能です。
p1のPUT文とp2のGET文のどちらが先に実行されるかは予測できません。
DECLARE STRUCTURE struct1 :3 OF NUMERIC
DECLARE SHARED share1 OF struct1
PARACT p1
START p2
FOR i=1 TO 10000
NEXT i
PUT TO share1 FROM 1,2,3
END PARACT
PARACT p2
GET FROM share1 TO a,b,c
PRINT A,B,C
END PARACT
-
- [8]
MESSAGE
- 投稿者:SHIRAISHI Kazuo
- 投稿日:2017年 4月30日(日)08時14分56秒
-
-
MESSAGE(通報)を利用すると同期をとりながらデータを受け渡すことができる。
DECLARE MESSAGE文で通報域の名称を宣言する。
SEND TO文で通報域にデータを送る。
SEND TO文は他の並行単位がRECEIVE FROM文を実行するまで待機する。
RECEIVE FROM文は,通報域からデータを受け取る。
RECEIVE FROM文は,通報域が空であれば,SEND TOが実行されてデータが送られてくるのを待つ。
RECEIVE FROM文を実行すると,通報域は空になる。
例
DECLARE STRUCTURE struct1 :3 OF NUMERIC
DECLARE MESSAGE mes1 OF struct1
PARACT p1
START p2
FOR i=1 TO 10
SEND TO mes1 FROM i,i^2,i^3
NEXT i
END PARACT
PARACT p2
FOR i=1 TO 10
RECEIVE FROM mes1 TO a,b,c
PRINT A,B,C
NEXT i
END PARACT
-
- [9]
デッドロック(deadrock)
- 投稿者:SHIRAISHI Kazuo
- 投稿日:2017年 4月30日(日)08時31分3秒
-
-
データ交換を目的に下のようなプログラムを書くと,相互に相手を待って身動きできなくなります。
注意が必要です。
例(deadrock)
DECLARE STRUCTURE struct1 :3 OF NUMERIC
DECLARE MESSAGE mes1 OF struct1
DECLARE MESSAGE mes2 OF struct1
PARACT p1
START p2
SEND TO mes1 FROM 1,2,3
RECEIVE FROM mes2 TO a,b,c
print a,b,c
END PARACT
PARACT p2
SEND TO mes2 FROM 4,5,6
RECEIVE FROM mes1 TO a,b,c
print a,b,c
END PARACT
-
- [12]
通報域を利用するデータ交換
- 投稿者:SHIRAISHI Kazuo
- 投稿日:2017年 4月30日(日)09時01分12秒
-
-
通報域を利用してデータを交換する場合は,1組のデータごとに授受を行う。
(そうしないとデッドロックを引き起こす)
例(正しい)
DECLARE STRUCTURE struct1 :3 OF NUMERIC
DECLARE MESSAGE mes1 OF struct1
DECLARE MESSAGE mes2 OF struct1
PARACT p1
START p2
SEND TO mes1 FROM 1,2,3
RECEIVE FROM mes2 TO a,b,c
print a,b,c
END PARACT
PARACT p2
RECEIVE FROM mes1 TO a,b,c
print a,b,c
SEND TO mes2 FROM 4,5,6
END PARACT
-
- [15]
SIGNAL文とWAIT EVENT文
- 投稿者:SHIRAISHI Kazuo
- 投稿日:2017年 4月30日(日)09時24分32秒
-
-
SIGNAL文は指定した名称のシグナルをONにします。
SIGNAL文はシグナルが受信されるのを待ちません。
WAIT EVENT文は,指定したシグナルがONになるのを待ち,シグナルをOFFにします。
例
DECLARE STRUCTURE struct1 :3 OF NUMERIC
DECLARE SHARED share1 OF struct1
DECLARE SHARED share2 OF struct1
PARACT p1
START p2
PUT TO share1 FROM 1,2,3
SIGNAL s1
WAIT EVENT s2
GET FROM share2 TO a,b,c
print a,b,c
END PARACT
PARACT p2
PUT TO share2 FROM 4,5,6
SIGNAL s2
WAIT EVENT s1
GET FROM share1 TO a,b,c
print a,b,c
END PARACT
-
- [16]
配列の受け渡し
- 投稿者:SHIRAISHI Kazuo
- 投稿日:2017年 4月30日(日)09時48分39秒
-
-
共用域,通報域には配列も使える。
その場合,次の例に示すようなSTRUCTURE宣言を書く。
例
DECLARE STRUCTURE struct2: 2 OF NUMERIC, NUMERIC(3,3)
DECLARE message m1 OF struct2
PARACT p1
START p2
DATA 1,2,3
DATA 4,5,6
DATA 7,8,9
DIM c(3,3)
LET a=12
LET b=13
MAT READ c
send TO m1 FROM a,b,c
END PARACT
PARACT p2
DIM c(3,3)
receive FROM m1 TO a,b,c
PRINT a,b
MAT PRINT c
END PARACT
-
- [17]
デッドロック(再)
- 投稿者:SHIRAISHI Kazuo
- 投稿日:2017年 4月30日(日)09時56分47秒
-
-
次のプログラムもデッドロックを招きます。
SEND TO文の実行が終了するためにはp2がRECEIVE文を実行する必要がありますが,
SEND TO文の実行が終わらないとSTART p2が実行できません。
例(deadrock)
DECLARE STRUCTURE struct2: 2 OF NUMERIC, NUMERIC(3,3)
DECLARE message m1 OF struct2
PARACT p1
DATA 1,2,3
DATA 4,5,6
DATA 7,8,9
DIM c(3,3)
LET a=12
LET b=13
MAT READ c
send TO m1 FROM a,b,c
START p2
END PARACT
PARACT p2
DIM c(3,3)
receive FROM m1 TO a,b,c
PRINT a,b
MAT PRINT c
END PARACT
-
- [18]
文字列変数
- 投稿者:SHIRAISHI Kazuo
- 投稿日:2017年 4月30日(日)12時13分14秒
-
-
共用域,通報域に文字列変数を使うこともできる。
STRUCTURE宣言でSTRINGを指定すればよい。
例
DECLARE STRUCTURE data: 1 of string(2), 2 of numeric(2)
DECLARE SHARED s1 OF data
PARACT p1
DIM s$(2), a(2), b(2)
DATA "Yamada", "Yoshida"
DATA 90, 80
DATA 70, 90
MAT READ s$
MAT READ a
MAT READ b
PUT TO s1 FROM s$, a, b
START p2
END paract
PARACT p2
DIM s$(2), a(2), b(2)
GET FROM s1 TO s$,a,b
MAT PRINT s$,a,b
END PARACT
-
- [19]
SEIZE
- 投稿者:SHIRAISHI Kazuo
- 投稿日:2017年 4月30日(日)13時57分57秒
-
-
Paract BASICでは,Full BASICのSEIZE文に(「SHARED」以外の)任意の名前を書くことができるようにしている。
同じ名前のSEIZE区は,ただひとつの並行活動のみがそれを実行でき,他の並行活動は,それが終わるのを待つ。
複数の並行活動が同時に
SET POINT COLOR ……
PLOT POINTS: ……
を実行すると,他の並行活動が指定した色で点が描かれてしまうことが起こる。
適当な名前,たとえば,ColorPointを指定したSEIZE~END SEIZEでくくると
PLOT POINTSを実行する直前に実行したSET POINT COLOR文が直前に書かれたものであることを保証できる。
次の例では,副プログラムmandelbが2つの並行活動から呼ばれ,並行して動く。
SEIZE文とEND SEIZE文を省いて実行すると,予期しない色指定が起こる。
DECLARE STRUCTURE struct2: 2 OF NUMERIC
DECLARE MESSAGE buff OF struct2
PARACT part1
START part2
LET left = -2
LET right= .8
LET h = (right - left)
SET WINDOW left, right,-h/2,h/2
DRAW axes
SET POINT STYLE 1
ASK PIXEL SIZE(left,-h/2;right,h/2) px,py
SEND TO buff FROM px,py
DECLARE EXTERNAL SUB mandelb
call mandelb(0,int(px/2),int(py/2),py)
END PARACT
PARACT part2
RECEIVE FROM buff TO px,py
DECLARE EXTERNAL SUB mandelb
CALL mandelb(INT(px/2)+1,px,INT(py/2),py)
END PARACT
EXTERNAL SUB mandelb(a0,a1,b0,b1)
FOR a=a0 TO a1
LET u=problemx(a)
FOR b=b0 TO b1
LET v=problemy(b)
LET x = 0
LET y = 0
FOR n = 1 TO 250
LET x1 = x^2 - y^2 + u
LET y1 = 2 * x * y + v
LET x = x1
LET y = y1
IF x^2+y^2>4 THEN
SEIZE colorPoint
SET POINT COLOR MIN(n,15)
PLOT POINTS: u,v
PLOT POINTS: u,-v
END SEIZE
EXIT FOR
END IF
NEXT n
NEXT b
NEXT a
END SUB
-
- [20]
SEIZE区の文法
- 投稿者:SHIRAISHI Kazuo
- 投稿日:2017年 4月30日(日)14時06分58秒
-
-
SEIZE区には文法上の制限がかかっている。
これらは,デッドロックを避けるための要請である。
1.SEIZE区は入れ子にできない。
2.SEIZE区の内部でCALL文,DRAW文の実行ができない。
3.SEIZE区の内部で利用者定義関数の呼び出しができない。
-
- [21]
モジュール
- 投稿者:SHIRAISHI Kazuo
- 投稿日:2017年 5月 1日(月)14時18分37秒
- 返信
-
-
モジュールを利用すれば複数の並行活動から共通にアクセス可能な共用メモリの確保が簡単にできますが,それは,複数の並行活動からの書き込みの競合という危険を伴います。
Full BASICのモジュール機能は,おそらくそれを避ける意図で主プログラムの代わりに並行単位を書くことを想定しない文書としたと考えられます。
Paract BASICは,並行単位とモジュールの双方を持つプログラムに対し警告しますが,強引に実行することも許します。
書き込みを行う並行活動が一つのみで,他の並行活動は読むだけであれば問題なく実行できるかもしれません。
-
- [22]
グラフィックス
- 投稿者:SHIRAISHI Kazuo
- 投稿日:2017年 5月 1日(月)14時35分10秒
-
-
図形機能はプログラム全体でひとつの存在です。
SET WINDOW文などは1回実行すれば十分です。並行単位ごとに書く必要はありませんし,また,そうすることは望ましくありません。
図形の変換を行う現在変形行列もプログラム全体でひとつです。複数の並行活動で DRAW … WITH を実行すると動作したとしても訳のわからない状態になります。
そのため並行活動を含むプログラムに DRAW … WITH を書くと警告するようにしていますが,変形を行う並行活動が1個のみであれば正常に動作する可能性があります。
-
- [23]
PLOT LINES
- 投稿者:SHIRAISHI Kazuo
- 投稿日:2017年 5月 1日(月)14時41分31秒
-
-
末尾にセミコロンを持つPLOT LINES文を複数の並行活動が同時に実行すると,線のつなぎ方がおかしくなります。
折れ線の描き始めから描き終わりまでをSEIZE~END SEIZEでくくり,それらのSEIZE区には同じ名前(たとえば,PlotLines)を付けてください。
線の色やスタイルなどが異なる場合には,それらを変更する命令もSEIZE区に含める必要があります。
Note.
DRAW GRID や DRAW AXES の実行中に別の並行活動で描画命令を実行しないでください。
例
PARACT p1
SET WINDOW -4,4,-4,4
DRAW grid
START p2
FOR k=1 TO 5 STEP 2
SEIZE plotlines
SET LINE COLOR k
SET LINE STYLE k
FOR x=-4 TO 4 STEP 0.1
PLOT LINES:x,x^k;
NEXT x
PLOT LINES
END SEIZE
NEXT k
END PARACT
PARACT p2
FOR k=2 TO 4 STEP 2
SEIZE plotlines
SET LINE COLOR k
SET LINE STYLE k
FOR x=-4 TO 4 STEP 0.1
PLOT LINES:x,x^k;
NEXT x
PLOT LINES
END SEIZE
NEXT k
END PARACT
-
- [24]
EAccessViolation
- 投稿者:SHIRAISHI Kazuo
- 投稿日:2017年 5月21日(日)08時35分32秒
-
-
実行開始直後,EAccessViolationのエラーが出るときは,
Outputフォルダの中身を削除し,ParactBASICを再起動してください。
Setup-Options の Time Delay Before Drawing Stratを変更すると効果があるかもしれません。
-
- [25]
BASICAcc2に改名しました
- 投稿者:SHIRAISHI kazuo
- 投稿日:2017年12月20日(水)07時53分15秒
-
-
BASICAcc2に改名しました。
描画を別スレッドで行うので,並行活動をもたないプログラムもBASICAcc Ver.1より高速になることが多いです。
-
- [26]
Paract BASICに戻りました
- 投稿者:白石 和夫
- 投稿日:2018年10月 9日(火)15時06分25秒
- 返信
-
-
再度,改名してParact BASICに戻りました。
並行活動を持たないプログラムはBASICAcc1.2のほうが高速です。
戻る