Linda
をテンプレートにして作成
[
トップ
] [
新規
|
一覧
|
単語検索
|
最終更新
|
ヘルプ
|
ログイン
]
開始行:
#contents
*Lindaライブラリ入手方法
Linda serverの本体と、通信プログラムの例です。 通信プログ...
の参考にして下さい。cvsでは、以下のプロジェクト名でチェッ...
Game_project/Linda
*Lindaの解説
**Lindaとは
Lindaとは、タプルと呼ばれるIDとDataがセットになったものを...
ントがサーバに対して out,in,rd などのコマンドを用いて読み...
#ref(linda.jpeg,center)
**サーバ (ldserv.c)
Lindaサーバのソースはldserv.cのみです。~
サーバは、新規にクライアントが接続
すると、タプルスペースのID65535にシーケンスな番号をデータ...
を蓄えます。クライアントがこのID65535からタプルを取得(in...
クライアント毎にユニークな番号を割り当てることができます。
**クライアントAPI (lindaapi.c,lindaapi.h)
タプル送受信のAPI(out,in,rdなど)を用いると、タプルはCOMMA...
また、サーバからのタプルの受信も psx_sync_n() を実行した...
ます。受信したタプルは REPLYキュー に蓄えられ、psx_reply(...
また、コールバックを用いて受信したときのアクションを登録...
**LindaのAPI
--void start_linda(hostname);
通信を初期化して、Linda APIが使用可能にする
--void psx_sync_n();
COMMANDキューに溜められたコマンドとデータをサーバ...
また、サーバからデータを取得し、REPLYキューへ溜め...
--int psx_out(int id, char *data, int size);
dataが示すアドレスから、指定したIDのタプルへsize byteの...
を 書き込むコマンド。返り値は、このコマンドのsequence番...
--int psx_in(int id);
指定したID番号のタプルから、データを読み込むコマンド。 ...
マンドを使用した場合、サーバー上に存在するタプルは、 ク...
ントがデータを読み込んだ後削除されます。 返り値として、
sequence番号を取得します。
--int psx_rd(int id);
指定したID番号のタプルから、データを読み込むコマンド。 ...
マンドを使用した場合、サーバー上に存在するタプルは、 ク...
ントがデータを読み込んだ後も残ります。 返り値として、seq...
番号を取得します。
--int psx_wait_rd(int id);
基本的に psx_rd() と同じですが、サーバの タプルスペース...
タがあってもすぐには読みこまず、 次にデータが書き込まれ...
待ちます。 データが書き込まれたときのみそのデータを読み...
クライアントへ送信します。 返り値として、sequence番号を...
ます。
--unsigned char psx_reply(int seq);
REPLYキューからデータを取り出すときに使用します。
psx_in/psx_rdで受け取ったsequence番号を引数とし手渡すと...
したデータがREPLYキューにある場合、 データが格納されている
TUPLEへのポインタを返します。 psx_replyによって返された...
タの先には、 先頭にそのTUPLEのヘッダ情報が 12bytes 格納...
いて、 その後にデータそのものが格納されています。
--int psx_callback_in(int id,void (*callback)(char *tuple...
サーバからデータを取得した際、REPLYキューに溜めずに任意...
を 呼び出すよう指定することができます。引き数の callback...
ポインタは psx_sync_n() の中で(データが到着したら)呼ばれ...
上記の psx_in / psx_rd / psx_wait_rd のコマンドの各々に...
psx_callback_in / psx_callback_rd / psx_callback_wait_rd...
意されています。細かな説明は後の方でします。
--int psx_get_datalength(unsigned char *tuple);
psx_reply()等で得たTUPLEのヘッダ部分からデータの...
を得る関数です。他にシーケンス番号、ID、モードの...
も用意しています。 (各々 psx_get_seq(), psx_get_i...
psx_get_mode())
**マクロ
LindaではTUPLEのヘッダ情報やデータ部分へアクセスするため...
セットと して以下のマクロを用意しています。
#define LINDA_MODE_OFFSET 0
#define LINDA_ID_OFFSET 1
#define LINDA_SEQ_OFFSET 3
#define LINDA_DATA_LENGTH_OFFSET 7
#define LINDA_HEADER_SIZE 12
これらはpsx_reply()で得たTUPLE(unsigned char のポインタ)...
やヘッダ部分などを取得するときなどに用いられます。データ...
ラミングの流れで示します。 以下はpsx_reply()で得たTUPLE (...
ダ部分を表示しているところです。
printf("MODE: %c\n",*(char*)(tuple+LINDA_MODE_OFFSET));
printf("ID: %d\n",*(short*)(tuple+LINDA_ID_OFFSET));
printf("SEQ: %d\n",*(int*)(tuple+LINDA_SEQ_OFFSET));
printf("DATA_LENGTH: %d\n",*(int*)(tuple+LINDA_DATA_LENG...
ヘッダ情報は異なるエンディアンのCPU上でも対応するように整...
トが配列の前の方にくるように揃えているので、予想した結果...
しれません。ヘッダ部分の情報を得るにはpsx_getから始まる関...
下さい。
*プログラミングの流れ
まずは、プログラム初頭でstart_linda(hostname)を 実行して...
**データを送信する場合
-psx_outでコマンドをキューに追加 (1)
psx_outした時点では、単にキューへためられるだけで、 まだ...
ていません。 Lindaでは、char型かunsigned char型でしかデー...
ができません。 ただ、符号の問題を避けるため、char型ではな...
char型を使いましょう。 少し詳しく言うと、psx_outは、与え...
のアドレスから、 1byteずつ順番に指定されたbyte数サーバー...
う事です。 そこで、送りたいデータを格納している変数や構造...
unsigned char型以外である場合、unsigned char型に タイプキ...
る必要があります。
-psx_sync_nで実際にコマンドを実行 (2)
この時、今までキューにためこまれたLindaのコマンドが、一気...
す。 PlayStation 2では、描画に関する演算はEmotion Engine...
ますが、実際の描画処理はGraphics Synthesizerで行われます...
画処理が行われている間、Emotion Engineには余裕ができます...
使用して、通信を行うようにプログラミングしましょう。 (そ...
考慮して、psx_sync_nを実行しましょう)
-受信相手のデータ受け取りの確認 (3)
通信を行う際、待ち合わせを行い、 データを受け取るまでゲー...
しまってはいけないので、 Lindaサーバーでは非同期通信を採...
もし送信するデータを確実に相手に受け取って欲しい場合は、 ...
取りのサイン(Ack)を受け取るようにするとよいでしょう。
例えば、送信側が psx_out() したデータを受信側が psx_in() ...
うな通信を何回か繰りかえす場合を考えます。 このとき、通信...
を受け取った事を確認してから、 次のデータを送らなければな...
も考えずにどんどんpsx_outを行うと、タプルにまだデータが残...
新たなデータを書き込めず、キューにためこまれていきます。 ...
がどんどん重くなってしまい、ゲーム自体もスピードが落ち、 ...
ぱいになると、失敗するようになってしまいます。 そこで、そ...
ために、相手がデータを受け取ったという サイン(Ack)を、psx...
使用して受け取ります。 Ackを受け取ってから、次のデータをp...
さい。 ただし、プログラムが通信を行う部分でループして、 A...
プログラムが止まるというわけではありません! メインの処理...
間も動き続ける書き方をして下さい!! そのために、psx_repl...
れているのです。
-(1)からを繰り返し行う (4)
**データを受信する場合(callbackを使わない)
-psx_in/psx_rd/psx_wait_rdでsequence番号を取得 (1)
sequence番号とは、実行したコマンドに与えられる、 整理券の...
ものです。
-psx_replyでデータの到着を監視 (2)
データが来ていれば、それに対する処理を実行する。 来ていな...
ままプログラムの処理を進める。
-データを任意の変数・構造体に展開 (3)
データを任意の変数・構造体に展開する際、 データを送信する...
ずつに分解されたデータ を、元の形に組み立てる必要がありま...
psx_reply() で得たポインタ(仮に reply とします)の 指す先...
ダが含まれているので、 実データ(RealData型とします)は
(RealData *)(reply + LINDA_HEADER_SIZE)
でアクセスできます。LINDA_HEADER_SIZE は 12 に置き換えら...
memcpyを使用すると便利です。
-psx_replyで受け取ったポインタをfreeする (4)
通信で受け取ったデータは、psx_sync_n()の実行時にmallocさ...
何処かへ蓄えられています。 それを放っておくと、データを受...
そのデータ分だけ メモリを消費し続ける事になり、メモリ不足...
ます。 よってデータを任意の変数・構造体に展開し終えた後に...
で得たポインタをfreeして下さい。 勿論、データを任意の変数...
納せずに、 psx_reply で得たポインタをそのまま使用しても構...
-送信相手へAckを送る (5)
必要ならば データを受け取ったというサインを送信者へ送りま...
Ack だと分かるものなら、送るデータは何でも構いません。
- (1)からを繰り返し行う (6)
**データを受信する場合(callbackを使う)
-psx_callback_in / psx_callback_rd / psx_callback_wait_rd...
callbackを使う場合は引き数にcallbackする関数と、 その関数...
る構造体を指定します。この callbackする関数の型は
void function(char * tuple, void * obj);
となっています。objは任意の構造体のポインタです。 この関...
は自由に作ってもいいのですが、 REPLYキューに蓄えられない...
psx_reply()を実行しても 答えは返ってきません。 引き数の t...
psx_sync_n() 内で malloc されているので、 いらなくなった...
ください。
データを受け取ったという情報をAckとして 送る場合などは、...
function() 内で送信する必要があります。
この callback 関数を上手く書くと、psx_reply() がいらない ...
ラムも可能です。
*Linda's Tips
Lindaでのプログラミングの際、以下のことに留意しておいて下...
-通信プログラムの例題が、Game_project/Linda/example にあ...
-IDの幅は、0〜65534です。
-65535のIDでpsx_inすると、Lindaサーバーから個別のIDを得ら...
-IDは、1から順に与えられます。また、IDはASCII文字で送られ...
-一度に送れるデータは、1つのタプルにつき、2^32-12bytes(in...
-NULLは送らないで下さい。
-コマンドをためすぎてキューがいっぱいになると失敗します。
終了行:
#contents
*Lindaライブラリ入手方法
Linda serverの本体と、通信プログラムの例です。 通信プログ...
の参考にして下さい。cvsでは、以下のプロジェクト名でチェッ...
Game_project/Linda
*Lindaの解説
**Lindaとは
Lindaとは、タプルと呼ばれるIDとDataがセットになったものを...
ントがサーバに対して out,in,rd などのコマンドを用いて読み...
#ref(linda.jpeg,center)
**サーバ (ldserv.c)
Lindaサーバのソースはldserv.cのみです。~
サーバは、新規にクライアントが接続
すると、タプルスペースのID65535にシーケンスな番号をデータ...
を蓄えます。クライアントがこのID65535からタプルを取得(in...
クライアント毎にユニークな番号を割り当てることができます。
**クライアントAPI (lindaapi.c,lindaapi.h)
タプル送受信のAPI(out,in,rdなど)を用いると、タプルはCOMMA...
また、サーバからのタプルの受信も psx_sync_n() を実行した...
ます。受信したタプルは REPLYキュー に蓄えられ、psx_reply(...
また、コールバックを用いて受信したときのアクションを登録...
**LindaのAPI
--void start_linda(hostname);
通信を初期化して、Linda APIが使用可能にする
--void psx_sync_n();
COMMANDキューに溜められたコマンドとデータをサーバ...
また、サーバからデータを取得し、REPLYキューへ溜め...
--int psx_out(int id, char *data, int size);
dataが示すアドレスから、指定したIDのタプルへsize byteの...
を 書き込むコマンド。返り値は、このコマンドのsequence番...
--int psx_in(int id);
指定したID番号のタプルから、データを読み込むコマンド。 ...
マンドを使用した場合、サーバー上に存在するタプルは、 ク...
ントがデータを読み込んだ後削除されます。 返り値として、
sequence番号を取得します。
--int psx_rd(int id);
指定したID番号のタプルから、データを読み込むコマンド。 ...
マンドを使用した場合、サーバー上に存在するタプルは、 ク...
ントがデータを読み込んだ後も残ります。 返り値として、seq...
番号を取得します。
--int psx_wait_rd(int id);
基本的に psx_rd() と同じですが、サーバの タプルスペース...
タがあってもすぐには読みこまず、 次にデータが書き込まれ...
待ちます。 データが書き込まれたときのみそのデータを読み...
クライアントへ送信します。 返り値として、sequence番号を...
ます。
--unsigned char psx_reply(int seq);
REPLYキューからデータを取り出すときに使用します。
psx_in/psx_rdで受け取ったsequence番号を引数とし手渡すと...
したデータがREPLYキューにある場合、 データが格納されている
TUPLEへのポインタを返します。 psx_replyによって返された...
タの先には、 先頭にそのTUPLEのヘッダ情報が 12bytes 格納...
いて、 その後にデータそのものが格納されています。
--int psx_callback_in(int id,void (*callback)(char *tuple...
サーバからデータを取得した際、REPLYキューに溜めずに任意...
を 呼び出すよう指定することができます。引き数の callback...
ポインタは psx_sync_n() の中で(データが到着したら)呼ばれ...
上記の psx_in / psx_rd / psx_wait_rd のコマンドの各々に...
psx_callback_in / psx_callback_rd / psx_callback_wait_rd...
意されています。細かな説明は後の方でします。
--int psx_get_datalength(unsigned char *tuple);
psx_reply()等で得たTUPLEのヘッダ部分からデータの...
を得る関数です。他にシーケンス番号、ID、モードの...
も用意しています。 (各々 psx_get_seq(), psx_get_i...
psx_get_mode())
**マクロ
LindaではTUPLEのヘッダ情報やデータ部分へアクセスするため...
セットと して以下のマクロを用意しています。
#define LINDA_MODE_OFFSET 0
#define LINDA_ID_OFFSET 1
#define LINDA_SEQ_OFFSET 3
#define LINDA_DATA_LENGTH_OFFSET 7
#define LINDA_HEADER_SIZE 12
これらはpsx_reply()で得たTUPLE(unsigned char のポインタ)...
やヘッダ部分などを取得するときなどに用いられます。データ...
ラミングの流れで示します。 以下はpsx_reply()で得たTUPLE (...
ダ部分を表示しているところです。
printf("MODE: %c\n",*(char*)(tuple+LINDA_MODE_OFFSET));
printf("ID: %d\n",*(short*)(tuple+LINDA_ID_OFFSET));
printf("SEQ: %d\n",*(int*)(tuple+LINDA_SEQ_OFFSET));
printf("DATA_LENGTH: %d\n",*(int*)(tuple+LINDA_DATA_LENG...
ヘッダ情報は異なるエンディアンのCPU上でも対応するように整...
トが配列の前の方にくるように揃えているので、予想した結果...
しれません。ヘッダ部分の情報を得るにはpsx_getから始まる関...
下さい。
*プログラミングの流れ
まずは、プログラム初頭でstart_linda(hostname)を 実行して...
**データを送信する場合
-psx_outでコマンドをキューに追加 (1)
psx_outした時点では、単にキューへためられるだけで、 まだ...
ていません。 Lindaでは、char型かunsigned char型でしかデー...
ができません。 ただ、符号の問題を避けるため、char型ではな...
char型を使いましょう。 少し詳しく言うと、psx_outは、与え...
のアドレスから、 1byteずつ順番に指定されたbyte数サーバー...
う事です。 そこで、送りたいデータを格納している変数や構造...
unsigned char型以外である場合、unsigned char型に タイプキ...
る必要があります。
-psx_sync_nで実際にコマンドを実行 (2)
この時、今までキューにためこまれたLindaのコマンドが、一気...
す。 PlayStation 2では、描画に関する演算はEmotion Engine...
ますが、実際の描画処理はGraphics Synthesizerで行われます...
画処理が行われている間、Emotion Engineには余裕ができます...
使用して、通信を行うようにプログラミングしましょう。 (そ...
考慮して、psx_sync_nを実行しましょう)
-受信相手のデータ受け取りの確認 (3)
通信を行う際、待ち合わせを行い、 データを受け取るまでゲー...
しまってはいけないので、 Lindaサーバーでは非同期通信を採...
もし送信するデータを確実に相手に受け取って欲しい場合は、 ...
取りのサイン(Ack)を受け取るようにするとよいでしょう。
例えば、送信側が psx_out() したデータを受信側が psx_in() ...
うな通信を何回か繰りかえす場合を考えます。 このとき、通信...
を受け取った事を確認してから、 次のデータを送らなければな...
も考えずにどんどんpsx_outを行うと、タプルにまだデータが残...
新たなデータを書き込めず、キューにためこまれていきます。 ...
がどんどん重くなってしまい、ゲーム自体もスピードが落ち、 ...
ぱいになると、失敗するようになってしまいます。 そこで、そ...
ために、相手がデータを受け取ったという サイン(Ack)を、psx...
使用して受け取ります。 Ackを受け取ってから、次のデータをp...
さい。 ただし、プログラムが通信を行う部分でループして、 A...
プログラムが止まるというわけではありません! メインの処理...
間も動き続ける書き方をして下さい!! そのために、psx_repl...
れているのです。
-(1)からを繰り返し行う (4)
**データを受信する場合(callbackを使わない)
-psx_in/psx_rd/psx_wait_rdでsequence番号を取得 (1)
sequence番号とは、実行したコマンドに与えられる、 整理券の...
ものです。
-psx_replyでデータの到着を監視 (2)
データが来ていれば、それに対する処理を実行する。 来ていな...
ままプログラムの処理を進める。
-データを任意の変数・構造体に展開 (3)
データを任意の変数・構造体に展開する際、 データを送信する...
ずつに分解されたデータ を、元の形に組み立てる必要がありま...
psx_reply() で得たポインタ(仮に reply とします)の 指す先...
ダが含まれているので、 実データ(RealData型とします)は
(RealData *)(reply + LINDA_HEADER_SIZE)
でアクセスできます。LINDA_HEADER_SIZE は 12 に置き換えら...
memcpyを使用すると便利です。
-psx_replyで受け取ったポインタをfreeする (4)
通信で受け取ったデータは、psx_sync_n()の実行時にmallocさ...
何処かへ蓄えられています。 それを放っておくと、データを受...
そのデータ分だけ メモリを消費し続ける事になり、メモリ不足...
ます。 よってデータを任意の変数・構造体に展開し終えた後に...
で得たポインタをfreeして下さい。 勿論、データを任意の変数...
納せずに、 psx_reply で得たポインタをそのまま使用しても構...
-送信相手へAckを送る (5)
必要ならば データを受け取ったというサインを送信者へ送りま...
Ack だと分かるものなら、送るデータは何でも構いません。
- (1)からを繰り返し行う (6)
**データを受信する場合(callbackを使う)
-psx_callback_in / psx_callback_rd / psx_callback_wait_rd...
callbackを使う場合は引き数にcallbackする関数と、 その関数...
る構造体を指定します。この callbackする関数の型は
void function(char * tuple, void * obj);
となっています。objは任意の構造体のポインタです。 この関...
は自由に作ってもいいのですが、 REPLYキューに蓄えられない...
psx_reply()を実行しても 答えは返ってきません。 引き数の t...
psx_sync_n() 内で malloc されているので、 いらなくなった...
ください。
データを受け取ったという情報をAckとして 送る場合などは、...
function() 内で送信する必要があります。
この callback 関数を上手く書くと、psx_reply() がいらない ...
ラムも可能です。
*Linda's Tips
Lindaでのプログラミングの際、以下のことに留意しておいて下...
-通信プログラムの例題が、Game_project/Linda/example にあ...
-IDの幅は、0〜65534です。
-65535のIDでpsx_inすると、Lindaサーバーから個別のIDを得ら...
-IDは、1から順に与えられます。また、IDはASCII文字で送られ...
-一度に送れるデータは、1つのタプルにつき、2^32-12bytes(in...
-NULLは送らないで下さい。
-コマンドをためすぎてキューがいっぱいになると失敗します。
ページ名: