JPWO2011158478A1 - データ処理システム及びデータ処理方法 - Google Patents

データ処理システム及びデータ処理方法 Download PDF

Info

Publication number
JPWO2011158478A1
JPWO2011158478A1 JP2012520284A JP2012520284A JPWO2011158478A1 JP WO2011158478 A1 JPWO2011158478 A1 JP WO2011158478A1 JP 2012520284 A JP2012520284 A JP 2012520284A JP 2012520284 A JP2012520284 A JP 2012520284A JP WO2011158478 A1 JPWO2011158478 A1 JP WO2011158478A1
Authority
JP
Japan
Prior art keywords
function
user
wrapper
argument
pointer
Prior art date
Legal status (The legal status is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the status listed.)
Granted
Application number
JP2012520284A
Other languages
English (en)
Other versions
JP5811088B2 (ja
Inventor
拓也 荒木
拓也 荒木
Current Assignee (The listed assignees may be inaccurate. Google has not performed a legal analysis and makes no representation or warranty as to the accuracy of the list.)
NEC Corp
Original Assignee
NEC Corp
Priority date (The priority date is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the date listed.)
Filing date
Publication date
Application filed by NEC Corp filed Critical NEC Corp
Priority to JP2012520284A priority Critical patent/JP5811088B2/ja
Publication of JPWO2011158478A1 publication Critical patent/JPWO2011158478A1/ja
Application granted granted Critical
Publication of JP5811088B2 publication Critical patent/JP5811088B2/ja
Active legal-status Critical Current
Anticipated expiration legal-status Critical

Links

Images

Classifications

    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F15/00Digital computers in general; Data processing equipment in general
    • G06F15/16Combinations of two or more digital computers each having at least an arithmetic unit, a program unit and a register, e.g. for a simultaneous processing of several programs
    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F9/00Arrangements for program control, e.g. control units
    • G06F9/06Arrangements for program control, e.g. control units using stored programs, i.e. using an internal store of processing equipment to receive or retain programs
    • G06F9/46Multiprogramming arrangements
    • G06F9/54Interprogram communication
    • G06F9/547Remote procedure calls [RPC]; Web services

Abstract

クライアント(300)は、ユーザ関数シンボル名を取得し、テンプレート関数として定義され、かつ、その内部でユーザ関数を実行するラッパ関数へのポインタを、ユーザ関数の引数及び戻り値の型をテンプレート引数として指定することにより、取得し、ラッパ関数へのポインタを用いてラッパ関数のラッパ関数シンボル名を取得する。サーバ(310)は、ユーザ関数シンボル名、ユーザ関数の引数に対応するデータ、ラッパ関数シンボル名、及び、ユーザプログラム及びラッパ関数が共有ライブラリとしてコンパイルされた共有ライブラリ化ユーザプログラムをクライアントから取得し、ユーザ関数シンボル名及びユーザ関数の引数に対応するデータを引数として、ラッパ関数へのポインタで特定される、共有ライブラリ化ユーザプログラム内のラッパ関数を実行する。

Description

本発明は、複数のコンピュータ装置をネットワークで結合して並列分散処理を実行するデータ処理技術に関する。
近年、複数のサーバをネットワークで結合し、これら複数のサーバ上でプログラムを並列に実行する、並列分散処理が行われている。
このような並列分散処理を行う場合、プログラマが通信処理を直接記述するのは煩雑なことから、遠隔呼出(Remote Procedure Call:RPC)が利用される場合がある。RPCは、ネットワークで結合された別のサーバ上の手続きの呼出を、通常の手続呼出と同様の書き方で実現するものである。
これにより、プログラマは煩雑な通信処理を直接記述せず、手続呼出と同様の記述をすることで、ネットワークで結合された別サーバに処理を行わせて並列分散処理を実現したり、データの授受を行ったりすることができる。
RPCシステムの一例が、下記非特許文献1に記載されている。このRPCシステムにおいては、RPCを介して呼び出される手続きのインタフェースがある特殊な言語で記述される。
この言語は、IDL(Interactive Data Language:インタフェース記述言語)と呼ばれることがある。ここでIDLに記述される内容は、呼び出される関数の名前や引数の数および型、返り値の型等である。
このIDLをIDLコンパイラによってコンパイルすると、クライアントスタブ、サーバスタブと呼ばれるCで記述されたプログラムが生成される。クライアントスタブ、サーバスタブには手続呼出をネットワークを介した別のサーバで行うための通信などの処理が記述されている。すなわち、サーバ側プログラムとして、IDLに記述された関数の定義が記述され、当該関数がサーバスタブとリンクされる。
そして、このプログラムが予めサーバ側で実行される。クライアント側プログラムとして、IDLに記述された関数を呼び出すプログラムが記述され、当該関数がクライアントスタブとリンクされる。クライアント側プログラムが実行されると、当該プログラムが、IDLで記述された関数を呼び出すところでサーバ側に接続し、サーバ側でその関数が実行されるようになる。
他の従来のRPCシステムの一例が、下記特許文献1に記載されている。この従来のRPCシステムでは、Java(登録商標)を対象とし、コンパイル済みのバイトコードを走査することでクライアントスタブ、サーバスタブに相当するプログラムが自動的に作成させる。これにより、IDLの記述が不要となる。
また、下記特許文献2には、クライアントサーバのRPCにおいて、サーバのライブラリメモリに各種ライブラリが予め格納され、クライアントから関数名称引数の情報がサーバに送信され、サーバは、当該情報に対応するライブラリプログラムをメモリから読み出して実行し、結果をクライアントに返す技術が開示されている。
特開平11−085519号公報 特開平11−338704号公報
「UNIXネットワークプログラミング」W.リチャード・スティーヴンス著 篠田陽一訳 トッパン、1992年7月30日、pp.809−829(UNIXは登録商標)
上記非特許文献1に記載されたシステムでは、RPCを利用するためにIDLを記述するのがプログラマにとって負担である。その理由は、IDLを用いる場合、IDLというプログラムを記述する言語とは別の言語を習得する必要があるためである。
また、RPCで呼び出す関数の引数の数や型、返り値の型等を変更した場合、プログラマは、IDLも変更し、両者の整合性をとる必要がある。さらに、プログラマは、新たな関数をRPCで呼び出したいと思った場合、IDLを変更しなければならない。
上記特許文献1に記載されたシステムでは、IDLを記述する負担は無いものの、利用できるプログラミング言語がJava(登録商標)等に限られる。その理由は、上記特許文献1に記載されたシステムは、コンパイル済みのバイトコードを走査することで、引数の数や型、返り値の型等のプログラムの情報を得ていると思われるためである。
Java(登録商標)のような言語のコンパイラが出力するバイトコードは、ネイティブコードまで変換されておらず、多くの情報を含むが、一般にCやC++といったネイティブコードにコンパイルする言語に比べると速度が遅い。したがって、CやC++といった、ネイティブコードにコンパイルするより高速な言語の場合には、上記特許文献1に記載された手法は利用できない。
上記特許文献2の技術は、OS(Operating System)レベルでの動作を想定しており、それを実現するためにはOSの変更が必要になる。さらに、「関数名称引数」をクライアント側が取得する方法、サーバがそれを受けとって関数を実行する具体的及び詳細な記述が無いため、実現方法が不明確である。
また、既存のシステムは、クライアント側プログラムとサーバ側プログラムとを別々のプログラムとして記述しなければならず、これがプログラマにとって負担となる。その理由は、RPCが並列分散処理によって速度を向上させるために利用される場合、分散実行処理を実行するプログラムは、1台のマシン上で実行されるプログラム(RPCを用いないプログラム)と可能な限り近い形態で記述できた方が、それができない場合よりも、プログラマにとっては負担が軽いためである。既存のシステムでは、分散実行する部分をサーバ側プログラムとして別に扱わなければならず、これがプログラマにとっては負担となる。
本発明は、上述のような課題に鑑みてなされたものであり、開発負荷を増加させることなく、様々な型の引数及び返り値を持つ関数を、或るコンピュータ装置からの指示により、他のコンピュータ装置上で実行させるデータ処理技術を提供するものである。
本発明の各態様では、上述した課題を解決するために、それぞれ以下の構成を採用する。
本発明の第1態様は、相互通信可能なクライアントとサーバとを含むデータ処理システムに関する。第1態様に係るデータ処理システムでは、クライアントは、ユーザプログラムに含まれるユーザ関数へのポインタが指すオブジェクトのユーザ関数シンボル名を取得するユーザ関数シンボル名取得部と、テンプレート関数として定義され、かつ、その内部でユーザ関数を実行するラッパ関数へのポインタを、ユーザ関数の引数及び戻り値の型をテンプレート引数として指定することにより、取得するラッパ関数ポインタ取得部と、ラッパ関数へのポインタを用いて、ラッパ関数のラッパ関数シンボル名を取得するラッパ関数シンボル名取得部と、を有し、サーバは、ユーザ関数シンボル名、ユーザ関数の引数に対応するデータ、ラッパ関数シンボル名、及び、ユーザプログラム及びラッパ関数が共有ライブラリとしてコンパイルされた共有ライブラリ化ユーザプログラムをクライアントから取得する通信部と、通信部により取得されたラッパ関数シンボル名を用いてラッパ関数へのポインタを取得するラッパ関数ポインタ取得部と、通信部により取得されたユーザ関数シンボル名及びユーザ関数の引数に対応するデータを引数として、ラッパ関数へのポインタで特定される、共有ライブラリ化ユーザプログラム内のラッパ関数を実行するラッパ関数実行部と、を有する。
本発明の第2態様に係るコンピュータ装置は、ユーザプログラムに含まれるユーザ関数へのポインタが指すオブジェクトのユーザ関数シンボル名を取得するユーザ関数シンボル名取得部と、テンプレート関数として定義され、かつ、その内部でユーザ関数を実行するラッパ関数へのポインタを、ユーザ関数の引数及び戻り値の型をテンプレート引数として指定することにより、取得するラッパ関数ポインタ取得部と、ラッパ関数へのポインタを用いて、ラッパ関数のラッパ関数シンボル名を取得するラッパ関数シンボル名取得部と、ユーザ関数シンボル名、ユーザ関数の引数に対応するデータ、ラッパ関数シンボル名、及び、ユーザプログラム及びラッパ関数が共有ライブラリとしてコンパイルされた共有ライブラリ化ユーザプログラムを他のコンピュータ装置へ送信する通信部と、を有する。
本発明の第3態様に係るコンピュータ装置は、ユーザプログラム、及び、テンプレート関数として定義され、かつ、その内部で当該ユーザプログラムに含まれるユーザ関数を実行するラッパ関数が、共有ライブラリとしてコンパイルされた共有ライブラリ化ユーザプログラム、ユーザ関数シンボル名、ユーザ関数の引数に対応するデータ、及び、ラッパ関数シンボル名を他のコンピュータ装置から取得する通信部と、通信部により取得されたラッパ関数シンボル名を用いてラッパ関数へのポインタを取得するラッパ関数ポインタ取得部と、通信部により取得されたユーザ関数シンボル名及びユーザ関数の引数に対応するデータを引数として、ラッパ関数へのポインタで特定される、共有ライブラリ化ユーザプログラム内のラッパ関数を実行するラッパ関数実行部と、を有する。
本発明の第4態様は、相互通信するクライアントとサーバとにより実行されるプログラムに関する。第4態様に係るプログラムは、クライアントに、ユーザプログラムに含まれるユーザ関数へのポインタが指すオブジェクトのユーザ関数シンボル名を取得するユーザ関数シンボル名取得部と、テンプレート関数として定義され、かつ、その内部でユーザ関数を実行するラッパ関数へのポインタを、ユーザ関数の引数及び戻り値の型をテンプレート引数として指定することにより、取得するラッパ関数ポインタ取得部と、ラッパ関数へのポインタを用いて、ラッパ関数のラッパ関数シンボル名を取得するラッパ関数シンボル名取得部と、を実現させ、サーバに、ユーザ関数シンボル名、ユーザ関数の引数に対応するデータ、ラッパ関数シンボル名、及び、ユーザプログラム及びラッパ関数が共有ライブラリとしてコンパイルされた共有ライブラリ化ユーザプログラムをクライアントから取得する通信部と、通信部により取得されたラッパ関数シンボル名を用いてラッパ関数へのポインタを取得するラッパ関数ポインタ取得部と、通信部により取得されたユーザ関数シンボル名及びユーザ関数の引数に対応するデータを引数として、ラッパ関数へのポインタで特定される、共有ライブラリ化ユーザプログラム内のラッパ関数を実行するラッパ関数実行部と、を実現させる。
本発明の第5態様は、相互通信するクライアントとサーバとにより実行されるデータ処理方法に関する。第5態様に係るデータ処理方法では、クライアントが、ユーザプログラムに含まれるユーザ関数へのポインタが指すオブジェクトのユーザ関数シンボル名を取得し、テンプレート関数として定義され、かつ、その内部でユーザ関数を実行するラッパ関数へのポインタを、ユーザ関数の引数及び戻り値の型をテンプレート引数として指定することにより、取得し、ラッパ関数へのポインタを用いて、ラッパ関数のラッパ関数シンボル名を取得し、サーバが、ユーザ関数シンボル名、ユーザ関数の引数に対応するデータ、ラッパ関数シンボル名、及び、ユーザプログラム及びラッパ関数が共有ライブラリとしてコンパイルされた共有ライブラリ化ユーザプログラムをクライアントから取得し、ラッパ関数シンボル名を用いてラッパ関数へのポインタを取得し、ユーザ関数シンボル名及びユーザ関数の引数に対応するデータを引数として、ラッパ関数へのポインタで特定される、共有ライブラリ化ユーザプログラム内のラッパ関数を実行する。
なお、本発明の各構成要素は、その機能を実現するように形成されていればよく、例えば、所定の機能を発揮する専用のハードウェア、所定の機能がコンピュータプログラムにより付与されたデータ処理装置、コンピュータプログラムによりデータ処理装置に実現された所定の機能、これらの任意の組み合わせ、等として実現することができる。
また、本発明の各構成要素は、必ずしも個々に独立した存在である必要はなく、複数の構成要素が一個の部材として形成されていること、一つの構成要素が複数の部材で形成されていること、ある構成要素が他の構成要素の一部であること、ある構成要素の一部と他の構成要素の一部とが重複していること、等でもよい。
また、本発明のコンピュータプログラムおよびデータ処理方法は、複数の処理および動作を順番に記載してあるが、複数の処理および複数の動作を実行する順番は、その記載の順番に限定されるものではない。このため、本発明のコンピュータプログラムおよびデータ処理方法を実施するときには、その複数の処理および複数の動作の順番は内容的に支障しない範囲で変更することができる。
さらに、本発明のコンピュータプログラムおよびデータ処理方法は、複数の処理および複数の動作が個々に相違するタイミングで実行されることに限定されない。このため、ある処理および動作の実行中に他の処理および動作が発生すること、ある処理および動作の実行タイミングと他の処理および動作の実行タイミングとの一部ないし全部が重複していてもよい。
また、本発明で云うデータ処理装置は、コンピュータプログラムを読み取って対応する処理動作を実行できるように、CPU(Central Processing Unit)、ROM(Read Only Memory)、RAM(Random Access Memory)、I/F(Interface)ユニット、等の汎用デバイスで構築されたハードウェア、所定の処理動作を実行するように構築された専用の論理回路、これらの組み合わせ、等として実現することができる。
上述の各態様によれば、開発負荷を増加させることなく、様々な型の引数及び返り値を持つ関数を、或るコンピュータ装置からの指示により、他のコンピュータ装置上で実行させるデータ処理技術を提供することができる。
図1は、本発明の参考例の構成を示すブロック図である。 図2は、本発明の参考例の動作を示すフローチャートである。 図3は、本発明の第一の実施形態の構成例を示すブロック図である。 図4は、本発明の第一の実施形態の動作例を示すフローチャートである。 図5は、本発明の第二の実施形態の構成例を示すブロック図である。 図6は、本発明の第一の実施例のユーザプログラムを示す模式図である。 図7は、本発明の第一の実施例のクライアントライブラリを示す模式図である。 図8は、本発明の第一の実施例のサーバライブラリを示す模式図である。 図9は、本発明の第二の実施例のユーザプログラムを示す模式図である。 図10は、本発明の第二の実施例のクライアントライブラリにおける、引数が一つのユーザ関数を対象にしたラッパ関数を示す模式図である。 図11は、本発明の第二の実施例のクライアントライブラリにおける、引数が一つのユーザ関数を対象にした「rpc」関数を示す模式図である。 図12は、本発明の第二の実施例のクライアントライブラリにおける、引数が二つのユーザ関数を対象にしたラッパ関数を示す模式図である。 図13は、本発明の第二の実施例のクライアントライブラリにおける、引数が二つのユーザ関数を対象にした「rpc」関数を示す模式図である。 図14は、本発明の第二の実施例のサーバライブラリを示す模式図である。
〔参考例〕
まず、本発明の参考例を図1および図2を参照して以下に説明する。図1に示されるように、本発明の参考例のデータ処理システムは、クライアント100とサーバ110とから構成される。
クライアント100は、ユーザプログラム101、クライアントライブラリ103等を有する。ユーザプログラム101は共有ライブラリ化ユーザプログラム102を持つ。クライアントライブラリ103はユーザ関数シンボル名取得部104と通信部105とを有する。
サーバ110は、サーバライブラリ111を有する。サーバライブラリ111は、通信部112、ユーザ関数ポインタ取得部113、ユーザ関数実行部115等を有する。サーバライブラリ111は、クライアント100から取得した共有ライブラリ化ユーザプログラム114をユーザ関数ポインタ取得部113からアクセスできる形で保持する。
これらは概略次のように動作する。ユーザは、ユーザプログラム101を記述し、ユーザプログラム101とクライアントライブラリ103とをリンクさせる。クライアントライブラリ103及びサーバライブラリ111は、ユーザプログラム101によらず同じものが利用される。
また、ユーザプログラム101をコンパイルすると、コンパイルされたユーザプログラム101は共有ライブラリとしても保存される。これは共有ライブラリ化ユーザプログラム102と表記される。
ユーザプログラム101内では、まず、初期化が行われる。この中で、ユーザプログラム101は、共有ライブラリ化ユーザプログラム102をクライアントライブラリ103に渡し、その共有ライブラリ化ユーザプログラム102を通信部105を経由してサーバ110に送信する。サーバ110は、通信部112でこれを受信し、受信された共有ライブラリ化ユーザプログラムをサーバライブラリ111の内部に共有ライブラリ化ユーザプログラム114として保持する。
初期化後、ユーザプログラム101は、サーバ110側で関数を呼び出す指示を行う。この関数を以後ユーザ関数と呼ぶ。ここで、ユーザプログラム101は、呼び出したいユーザ関数へのポインタと、その引数をクライアントライブラリ103に渡す。
クライアントライブラリ103では、ユーザ関数シンボル名取得部104が、そのユーザ関数ポインタが指すオブジェクトのユーザ関数シンボル名を取得する。この取得処理は、例えば、Linuxの場合、「dladdr」関数を用いることで実現可能である。
クライアントライブラリ103は、このシンボル名と与えられた引数とを通信部105を経由してサーバ110に送信する。サーバ110は、通信部112で、それらを受信する。
サーバ110は、ユーザ関数のシンボル名をユーザ関数ポインタ取得部113に渡す。ユーザ関数ポインタ取得部113は、初期化時に取得した共有ライブラリ化ユーザプログラム114、およびユーザ関数シンボル名から、呼び出すべきユーザ関数へのポインタを取得する。この取得処理は、例えば、Linuxの場合、「dlopen」関数で共有ライブラリをオープンし、そこで得られたハンドルと、ユーザ関数シンボル名を引数にして「dlsym」関数を呼び出すことで実現され得る。
ユーザ関数実行部115は、このユーザ関数ポインタと、引数を用いて、ユーザ関数を実行する。ユーザ関数実行部115は、その実行結果の返り値を通信部112を経由してクライアント100に送信する。
クライアントライブラリ103は、通信部105で関数の実行結果である返り値を受信する。クライアントライブラリ103は、受信された返り値をユーザプログラム101に返す。このようにすることで、クライアント100からの指示により、指定された関数をサーバ110側で実行することが可能となる。
次に、図1および図2を参照して本参考例の全体の動作について詳細に説明する。まず、ユーザプログラム101は、共有ライブラリ化ユーザプログラム102を指定して初期化を実行する(図2のステップ201)。
これにより、クライアントライブラリ103が、共有ライブラリ化ユーザプログラム102をサーバ110に送信する(ステップ211)。サーバライブラリ111は、これを受信し(ステップ221)、受信された共有ライブラリ化ユーザプログラムをサーバライブラリ111に登録する(ステップ222)。
次に、ユーザプログラム101が、サーバ110でユーザ関数を実行するために、ユーザ関数ポインタと引数をクライアントライブラリ103に渡す(ステップ202)。クライアントライブラリ103はこれを受け取り(ステップ212)、ユーザ関数ポインタを用いてユーザ関数シンボル名を取得する(ステップ213)。クライアントライブラリ103は、得られたユーザ関数シンボル名と引数をサーバ110に送信する(ステップ214)。
サーバライブラリ111は、ユーザ関数シンボル名と引数を受信し(ステップ223)、ユーザ関数シンボル名と登録しておいた共有ライブラリ化ユーザプログラム114からユーザ関数ポインタを取得する(ステップ224)。サーバライブラリ111は、このユーザ関数ポインタと引数を用いてユーザ関数を実行し(ステップ225)、その結果の返り値をクライアントライブラリ103に送信する(ステップ226)。
クライアントライブラリ103はこれを受信し(ステップ215)、その受信された返り値をユーザプログラム101に返す(ステップ203)。ステップ202から203を繰り返すことで、ユーザプログラム101は複数回、サーバ110側で関数を実行することが可能である。
〔第一の実施形態〕
次に、本発明の第一の実施形態について図3および図4を参照して詳細に説明する。
ところで、上述の参考例においては、サーバ110側で実行される関数の引数の数や型、返り値の型が指定できず、固定になっていた。その理由は、関数ポインタをユーザ関数ポインタ取得部113で取得するだけでは、その関数の引数の数や型の情報は得られないからである。第一の実施形態はこの点を解決している。
図3に示されるように、第一の実施形態におけるデータ処理システムは、クライアント300とサーバ310から構成される。クライアント300とサーバ310とは相互に通信する。
クライアント300は、ユーザプログラム301とクライアントライブラリ303とを有する。ユーザプログラム301は共有ライブラリ化ユーザプログラム302を持つ。共有ライブラリ化ユーザプログラム302は、ユーザプログラム301が共有ライブラリとしてコンパイルされることにより得られる。
クライアントライブラリ303は、ユーザ関数シンボル名取得部304と、ラッパ関数ポインタ取得部305、ラッパ関数シンボル名取得部306、シリアライズ部307、デシリアライズ部308、通信部309等を含む。
ユーザ関数シンボル名取得部304は、関数へのポインタが指すオブジェクトのユーザ関数シンボル名を取得する。ラッパ関数ポインタ取得部305は、テンプレート関数として定義され、かつ、その内部でユーザ関数を実行するラッパ関数へのポインタを、ユーザ関数の引数及び戻り値の型をテンプレート引数として指定することにより、取得する。ラッパ関数シンボル名取得部306は、ラッパ関数へのポインタを用いて、ラッパ関数シンボル名を取得する。
サーバ310はサーバライブラリ311を有する。サーバライブラリ311は、通信部312、ラッパ関数ポインタ取得部313、ラッパ関数実行部315等を含む。通信部31は、例えば、ユーザ関数シンボル名、ユーザ関数の引数に対応するデータ、ラッパ関数シンボル名、及び、ユーザプログラム及びラッパ関数が共有ライブラリとしてコンパイルされた共有ライブラリ化ユーザプログラムをクライアント300から取得する。ラッパ関数ポインタ取得部313は、通信部31により取得されたラッパ関数シンボル名を用いて、ラッパ関数へのポインタを取得する。
ラッパ関数実行部315は、ユーザ関数ポインタ取得部316、ユーザ関数実行部319、デシリアライズ部317、シリアライズ部318等を含む。ラッパ関数実行部315は、これら各処理部を用いて、ユーザ関数シンボル名とシリアライズされたユーザ関数の引数に基づいてラッパ関数を実行する。
サーバライブラリ311は、クライアント300から取得した共有ライブラリ化ユーザプログラム314をラッパ関数ポインタ取得部313および、ユーザ関数ポインタ取得部316からアクセスできる形で保持する。ユーザ関数ポインタ取得部316は、初期化時に取得された共有ライブラリ化ユーザプログラム314およびユーザ関数シンボル名により呼び出すべきユーザ関数へのユーザ関数ポインタを取得する。ユーザ関数実行部319は、ユーザ関数ポインタと引数を用いてユーザ関数を実行する。
このような第一の実施形態におけるデータ処理システムの動作を説明する前に、ここで、上述の参考例と異なる「ラッパ関数」について説明する。この「ラッパ関数」を用いることにより、任意の型の引数、返り値を持つユーザ関数を実行することが可能となる。
ラッパ関数の実現のため、本実施の形態では、C++のような、ジェネリックプログラミングの機能(C++ではテンプレートと呼ぶため以下テンプレートと記述する)を使って関数を記述でき、かつ型を指定した関数の生成がコンパイル時に行われるプログラミング言語を用いる。
例えば、C++のテンプレートを用いると、以下のような関数を記述できる。
template <class T>
T add(T a, T b){return a+b;}
このような関数定義があった場合、
add<double>(1.0, 2.0)
と記述した場合、データ型「T」を「double」とした関数「add」が利用され得る。
これは、コンパイラが、
double add_double(double a, double b){return a+b;}
のような関数を内部で自動的に生成することで実現されている。
このような機能を用い、第一の実施形態は、ユーザ関数をその中から呼び出す「ラッパ関数」をテンプレート関数として導入する。そのテンプレート引数としてはユーザ関数の引数や返り値の型が定義される。
ラッパ関数自身の引数や返り値は、これらの型に依存せず、固定のものとする。したがって、ラッパ関数自身は、上述の参考例と同様の方法でサーバ310側で呼び出せる。一方、ラッパ関数は、テンプレート引数として得られたユーザ関数の引数や返り値の型を用い、ユーザ関数をその引数や返り値の型に応じて実行する。これによって、任意の型の引数、返り値を持つユーザ関数を実行できるようになる。
ラッパ関数は、引数として、ユーザ関数のシンボル名、ユーザ関数の引数をシリアライズしたものを取り、返り値としてシリアライズされたユーザ関数の返り値を返す。なお、ラッパ関数の返り値は、引数として取得されたポインタを用いて返されてもよい。以降の説明では、ラッパ関数の返り値は、返り値として返す例を用いる。
ここで、シリアライズとは、複数の変数を一つのバイト列等に変換する操作である。シリアライズされたバイト列等から元の変数を復元する操作をデシリアライズと呼ぶ。ラッパ関数は、テンプレート引数に指定された型を用いて、シリアライズされたデータからユーザ関数の引数をデシリアライズして復元する。
同様に、ラッパ関数は、テンプレート引数に指定された型を用いて、ユーザ関数の関数ポインタをその型に応じて取得する。そして、ラッパ関数は、この関数ポインタと引数を用いてユーザ関数を実行する。ユーザ関数の実行結果の返り値はシリアライズされラッパ関数の返り値として返される。
このようなラッパ関数は、テンプレート引数に応じ、ラッパ関数ポインタ取得部305で、ラッパ関数へのポインタを取得する部分で、コンパイラによって生成される。したがって、ラッパ関数は、共有ライブラリ化ユーザプログラム302、314にも含まれる。
このようなラッパ関数が定義されているとして、第一の実施形態の動作について説明する。まず、上述の参考例と同様に、ユーザはユーザプログラム301を記述し、ユーザプログラム301とクライアントライブラリ303とがリンクされる。
ここで、クライアントライブラリ303の一部は上記のテンプレート関数として定義されている。例えばC++の場合、ヘッダファイル内に定義されており、コンパイル時にも利用される。
上述の参考例と同様に、ユーザプログラム301をコンパイルすると、コンパイルされたユーザプログラム301は共有ライブラリとしても保存される。これが、共有ライブラリ化ユーザプログラム302と表記される。
ユーザプログラム301内では、上述の参考例と同様に、まず、初期化が行われる。この中で、ユーザプログラム301は、共有ライブラリ化ユーザプログラム302をクライアントライブラリ303に渡し、共有ライブラリ化ユーザプログラム302を通信部309を経由してサーバ310に送信する。サーバ310は、通信部312でこれを受信し、受信された共有ライブラリ化ユーザプログラムをサーバライブラリ311内に共有ライブラリ化ユーザプログラム314として保存する。
続いて、ユーザプログラム301は、参考例と同様に、ユーザ関数ポインタと引数をクライアントライブラリ303に渡す。ここで、呼び出されるクライアントライブラリ303の関数は、テンプレート関数で実現され、ユーザ関数の引数や返り値の型をテンプレート引数として取る。
クライアントライブラリ303では、ユーザ関数シンボル名取得部304が、そのユーザ関数ポインタが指す、オブジェクトファイル内におけるオブジェクトのシンボル名を取得する。クライアントライブラリ303は、ユーザプログラム301から与えられた引数に対し、シリアライズ部307においてシリアライズを行う。
さらに、ラッパ関数ポインタ取得部305が、クライアントライブラリ303にテンプレート引数として与えられた型を指定して、ラッパ関数ポインタを取得する。そして、そのラッパ関数ポインタを用いて、ラッパ関数シンボル名取得部306が、ラッパ関数のシンボル名を取得する。
通信部309は、ラッパ関数シンボル名、ユーザ関数シンボル名、シリアライズされた引数をサーバ310に渡す。サーバ310は、通信部312を経由してこれらを受け取る。
サーバ310では、ラッパ関数ポインタ取得部313が、ラッパ関数シンボル名と共有ライブラリ化ユーザプログラム314から、ラッパ関数ポインタを取得する。サーバライブラリ311では、ラッパ関数実行部315が、この取得されたラッパ関数ポインタで特定されるラッパ関数を、ユーザ関数シンボル名と、シリアライズされたユーザ関数の引数とを引数として実行する。
ラッパ関数は、上述したとおり、共有ライブラリ化ユーザプログラム314とユーザ関数シンボル名とからユーザ関数ポインタを取得する。また、ラッパ関数は、シリアライズされた引数をデシリアライズし、ユーザ関数の引数を取得する。ラッパ関数は、取得されたユーザ関数の引数を用いて、上記ユーザ関数ポインタにより特定されるユーザ関数を実行し、その返り値をシリアライズし、シリアライズされた返り値をラッパ関数の返り値として返す。
シリアライズされた返り値は通信部312を経由してクライアント300に返される。クライアント300では、通信部309がこれを受け取り、デシリアライズ部308がその返り値をデシリアライズする。そして、デシリアライズされた返り値がユーザプログラム301に返される。
次に、図3および図4を参照して、第一の実施形態の全体の動作について詳細に説明する。まず、ユーザプログラム301が、共有ライブラリ化ユーザプログラム302を指定して初期化を実行する(図4のステップ401)。
これにより、クライアントライブラリ303が、共有ライブラリ化ユーザプログラム302をサーバ310に送信する(ステップ411)。サーバライブラリ311は、これを受信し(ステップ421)、受信された共有ライブラリ化ユーザプログラムをサーバライブラリ311に登録する(ステップ422)。
次に、ユーザプログラム301が、サーバ310でユーザ関数を実行するために、ユーザ関数ポインタと引数をクライアントライブラリ303に渡す(ステップ402)。クライアントライブラリ303は、これを受け取り(ステップ412)、ユーザ関数ポインタを用いてユーザ関数シンボル名を取得する(ステップ413)。
次に、クライアントライブラリ303は、取得された引数をシリアライズする(ステップ414)。そして、クライアントライブラリ303は、ラッパ関数のポインタを取得し(ステップ415)、ラッパ関数ポインタからラッパ関数シンボル名を取得する(ステップ416)。クライアントライブラリ303は、ユーザ関数シンボル名、シリアライズされた引数、ラッパ関数シンボル名をサーバ310に送信する(ステップ417)。
サーバ310は、ユーザ関数シンボル名、シリアライズされた引数、ラッパ関数シンボル名を受信する(ステップ423)。サーバライブラリ311は、受信されたラッパ関数シンボル名と共有ライブラリ化ユーザプログラム314とを用いてラッパ関数ポインタを取得し(ステップ424)、ユーザ関数シンボル名とシリアライズされた引数を用いてラッパ関数を実行する(ステップ425)。
実行されたラッパ関数内では、まず、ユーザ関数シンボル名と共有ライブラリ化ユーザプログラム314に基づいて、ユーザ関数ポインタが取得される(ステップ426)。そして、シリアライズされた引数がデシリアライズされ、引数が復元される(ステップ427)。
ラッパ関数は、これらを用い、ユーザ関数を実行する(ステップ428)。ラッパ関数は、ユーザ関数の返り値をシリアライズする(ステップ429)。このシリアライズされたユーザ関数の返り値は、ラッパ関数の返り値として返される、サーバライブラリ311は、シリアライズされたユーザ関数の返り値を、クライアント300に送信する(ステップ4210)。
クライアントライブラリ303は、シリアライズされた返り値を受信し(ステップ418)、これをデシリアライズする(ステップ419)。そして、クライアントライブラリ303は、このデシリアライズされた返り値をユーザプログラム301に返す(ステップ403)。
次に、上述の第一の実施形態の作用及び効果について説明する。上述の第一の実施形態では、任意の型の引数、返り値を持つユーザ関数を内部で呼び出すラッパ関数がテンプレート関数として定義され、ラッパ関数自身の引数、返り値の型が固定され、このラッパ関数がサーバ310側で呼び出される。これにより、第一の実施形態によれば、様々な型の引数、返り値を持つユーザ関数をサーバ310側で呼び出すことができる。
上述の第一の実施形態におけるデータ処理システムでは、クライアント300側で共有ライブラリ化されたユーザプログラム302、及び、呼び出す関数のシンボル名がクライアント300からサーバ310に送信され、サーバ310側で、シンボル名と共有ライブラリ化したユーザプログラム302から呼び出すべき関数ポインタが取得され、ユーザ関数が実行されるというように、RPCが実現される。これにより、第一の実施形態によれば、CやC++といったネイティブコードにコンパイルする言語を採用し、IDLを用いず、RPCを記述することができる。
更に、第一の実施形態によれば、サーバ310側のプログラムとクライアント300側のプログラムを別々に記述することなく、RPCを実現することができる。その理由は、サーバ310は、ユーザプログラムによらないサーバライブラリ311を用い、共有ライブラリ化したユーザプログラム302(314)を受信することで、ユーザプログラム内で定義された関数をサーバ310側で実行するからである。更に、第一の実施形態によれば、OSレベルでの動作を想定していないので、OSの変更が必要なく、既存OS上で動作するライブラリとして実現することができるので、有用性が高い。
〔第二の実施形態〕
次に、第二の実施形態について図5を参照して詳細に説明する。第二の実施形態におけるデータ処理システムは、図5に示されるような、ハードウェア構成を持つ。クライアント500は、少なくとも1つのコンピュータ501、記憶媒体502等から構成され、サーバ510は、少なくとも1つのコンピュータ511、記憶媒体512等から構成される。
コンピュータ501及び511は、相互に接続される、CPU(Central Processing Unit)、メモリ、入出力インタフェース(I/F)等を有する。記憶媒体502及び512は、例えば、ハードディスク、CD、DVD、ブルーレイ等のような媒体である。記憶媒体502及び512は、上述の第一の実施形態におけるユーザプログラム301、共有ライブラリ化ユーザプログラム302、クライアントライブラリ303、サーバライブラリ311等を格納する。コンピュータ501及び511は、記憶媒体502及び512に格納されるそれらプログラムを読出し、読み出されたプログラムをCPUで実行することにより、上述の第一の実施形態におけるデータ処理システムを実現する。
第二の実施形態では、第一の実施形態におけるクライアントライブラリ303に含まれる、ユーザ関数シンボル名取得部304、ラッパ関数ポインタ取得部305、ラッパ関数シンボル名取得部306、シリアライズ部307、デシリアライズ部308、及び通信部309は、ソフトウェア要素として実現される。これらソフトウェア要素は、例えば、クライアントライブラリ303に含まれるモジュール又はコンピュータ501のOS(図示せず)で提供されるモジュールがCPUにより実行されることにより実現される。
また、第二の実施形態では、第一の実施形態におけるサーバライブラリ311に含まれる、ラッパ関数実行部315、ラッパ関数ポインタ取得部313、通信部312、ユーザ関数実行部319、シリアライズ部318、デシリアライズ部317、ユーザ関数ポインタ取得部316も、ソフトウェア要素として実現される。これらソフトウェア要素は、例えば、サーバライブラリ311に含まれるモジュール又はコンピュータ511のOS(図示せず)で提供されるモジュールがCPUにより実行されることにより実現される。
また、上述の第一の実施形態では特に明記はしなかったが、ユーザプログラム301、クライアントライブラリ303、サーバライブラリ311等を実行形式(ネイティブコード)に変換するソフトウェアであるコンパイラ(リンカ等も含む)も、コンピュータ501又511は保持する。第一実施形態における各処理部が実現されるにあたり、これらコンパイラがコンピュータ501又は511で実行される。
よって、第二の実施形態では、第一の実施形態の動作の説明における、動作主体(ユーザプログラム301、クライアントライブラリ303、サーバライブラリ311、ラッパ関数など)はCPUに置き換えることができる。この点、以下の実施例でも同様である。
[実施例]
次に、具体的な本発明の実施例の動作を図6から図14を用いて以下に説明する。ここでは、実施例として、Linux OS上で実行される、C言語あるいはC++言語により記述されたソースコードが例示される。但し、各図に示されるソースコードは、部分的に例示されたものであるため、そのまま動作するものではない。
図6から図8に、第一の実施例が示される。図6はユーザプログラムを示し、図7はクライアントライブラリを示し、図8はサーバライブラリを示す。
図6のユーザプログラムでは、「userfunc1」及び「userfunc2」という関数(ユーザ関数)が定義されている。これらがサーバで実行したい関数である。参考例では、これらの関数の引数の数や型、返り値の型は固定となる。本参考例における各関数は、「int」型の引数を一つとり、「int」型の返り値を返す関数として定義されている。
main()の中では、まずIPアドレス等を含むサーバの情報がNode型変数である「server」に取得される。Node型はライブラリ内で定義されているものとする。
次に、関数「init」が呼び出されることにより、初期化が行われる。関数「init」の引数には、変数「server」と、共有ライブラリ化ユーザプログラムのファイル名が渡される。すなわち、関数「userfunc1」及び「userfunc2」が、共有ライブラリとしてこのファイル名で示されるファイル内に存在することになる。
次の行の記述「rpc(server, userfunc1, 1)」により、サーバ側で関数「userfunc1(1)」が呼び出され、その返り値が「rpc」関数の返り値として得られる。この例の場合は「2」が返り値として返る。関数「userfunc2」についても同様に実行される。
次に、図7を参照し、クライアントライブラリ303について説明する。クライアントライブラリ303では、ユーザプログラムから呼び出される関数「init」および関数「rpc」が定義されている。
「init」関数が実行されると、サーバに共有ライブラリ化ユーザプログラムが送信される。そのため、「init」関数内では、まず、「connect_to_server」関数が実行されることにより、サーバへの接続が実現される。この実施例では、この関数は、Node型変数を受け取り、このNode型変数で示されるサーバに接続した後、ソケットを示すファイルディスクリプタを返す。
次に、ファイル名で指定された共有ライブラリ化ユーザプログラムが、「raed_from_file」関数により読み取られる。この関数は、ファイルからその内容を読み取り、読み取られた内容を第一引数で与えられた「char」型のポインタが指すメモリ領域に書き込む。なお、ここでは、変数の宣言やメモリ確保及び解放などは省略されている。そして、読み込んだバイト数が戻される。
次に、「write_to_socket」関数がサーバにファイルの内容を送信する。この関数は、ソケットと送信すべきデータが入った「char」型のポインタ、およびそのサイズを指定することで、データをサーバに送信する。最後に、「close_connection」関数が呼び出される。この関数は、「connect_to_server」関数で作成されたソケットをクローズする。
次に、「rpc」関数について説明する。「rpc」関数の中では、「get_symbol」関数が利用されているため、これについて、まず説明する。「get_symbol」関数は、関数ポインタを受け取り、OSが提供する「dladdr」関数を呼び出すことで、関数ポインタのシンボル名を取得する。「dladdr」関数には、関数ポインタと、OSが定義する「Dl_info」型の変数へのポインタを渡すことで、「Dl_info」型変数の「dl_sname」メンバにその関数のシンボル名が返される。
次に「rpc」関数の動作について説明する。「rpc」関数は、上述の「get_symbol」関数を用い、引数として与えられた関数ポインタのシンボル名を取得する。次に、上述と同様に「connect_to_server」関数を用いてサーバに接続し、ソケットのファイルディスクリプタを取得する。
そして、「rpc」関数は、「write_to_socket」関数を用いて、まず、ユーザ関数シンボル名をサーバに送信する。そのため、引数に、ソケットのファイルディスクリプタ、ユーザ関数シンボル名、及びそのサイズが渡される。
次に、「rpc」関数は、引数をサーバに送信する。そのため、「write_to_socket」関数の引数として、ファイルディスクリプタと、引数を「char」型のポインタ型にキャストしたもの、そしてsizeof(int)(この例では「int」型)が渡される。
次に、「rpc」関数は、「read_from_socket」関数を用い、実行結果をサーバから受け取る。この関数は、ソケットのファイルディスクリプタと、「char」型のポインタを受け取り、実行結果のデータをサーバから受け取る。続いて、「rpc」関数は、変数「ret」に、サーバから受け取った値(変数「buf」の値)を「int」型にキャストした上で設定する。最後に、「rpc」関数は、「close_connection」関数でソケットをクローズし、変数「ret」の値をrpc関数の返り値として返す。
次に、図8を参照してサーバライブラリの動作について説明する。
サーバライブラリでは、まず、「accept_connection」関数が、クライアントからの接続を受け付ける。図8の例では、この関数は、クライアントによる「connect_to_server」関数の実行に応答し、接続を確立する。この関数は、返り値として、ソケットのファイルディスクリプタを返す。なお、接続ごとにプロセスがフォークされ、接続ごとに別プロセスが生成されてもよい。この場合、親プロセスは、「accept_connection」関数の実行に戻り、子プロセスは以下の処理を行う。
サーバは、この接続を用い、クライアントから共有ライブラリ化ユーザプログラムを「read_from_socket」関数で受信する。「read_from_socket」関数は返り値として読み込んだバイト数を返す。
次に、メモリ上に読み込んだ共有ライブラリ化ユーザプログラムをファイルに書き込むため「write_to_file」関数が呼び出される。この関数は、ファイル名と、共有ライブラリ化ユーザプログラムが読み込まれたメモリ領域へのポインタ、そのサイズを指定して、共有ライブラリ化ユーザプログラムを引数のファイル名により示されるファイルに書き込む。ここでは、書き込み先のファイル名として「/tmp/tmpfile.so」が指定されている。
そして、OSが提供する関数である「dlopen」により、この共有ライブラリがオープンされる。引数には書き込まれたファイルのファイル名と、「dlopen」の動作を決めるフラグが指定される(ここではRTLD_LAZYを指定している)。「dlopen」の返り値は「ハンドル」であり、これを後で利用する。
そして、「close_connection」関数が呼び出され、クライアントとの接続がクローズされる。この後、サーバはクライアントからのユーザ関数実行要求を受け付けるためのループを実行する。
まず、サーバは、「accept_connection」関数により、クライアントからの接続を受け付ける。なお、あるユーザ関数実行中にも他のユーザ関数実行要求を同時に受け付けるため、以下のユーザ関数実行のための処理が別スレッドで行われるようにしてもよい。
この場合、親スレッドは、「accept_connection」関数の実行に戻り、生成されたスレッドが以下の処理を行う。プロセスではなくスレッドを用いることで、ユーザ関数がグローバル変数に値を設定した場合などに、後で呼び出すユーザ関数呼び出しからその値を利用することができるようになる。
次に、「read_from_socket」関数で、ユーザ関数シンボル名が受信される。更に続く「read_from_socket」関数で、引数が受信される。引数は、int型にキャストされる。続く、「typedef」は、呼び出す関数の型を「functype」として定義する。この実施例では、「functype」は、「int」型の値を引数にし、「int」型の値を返す関数へのポインタ型として定義されている。
そして、サーバは、OSが提供する関数である「dlsym」を呼び出すことで、呼び出すべき関数へのポインタを取得する。「dlsym」関数の引数は、「dlopen」関数の実行によって得られたハンドルと、関数のシンボル名である。「dlsym」関数の返り値として関数へのポインタが得られるので、このポインタが「functype」型の変数にキャストされ、代入される。
そして、サーバは、この関数へのポインタに対し、引数を与えることにより、当該関数を実行する。この関数の返り値は、「write_to_socket」関数によって、クライアントに送信される。最後に、サーバは、「close_socket」関数で接続をクローズし、ループの先頭に戻る。
次に、第二の実施例について図9から図14を用いて説明する。図9はユーザプログラムを示し、図10から図13はクライアントライブラリを示し、図14はサーバライブラリを示す。
まず、図9のユーザプログラムについて説明する。これは第一の実施例とほとんど同じであるが、サーバで呼び出される関数の型および引数の数が変更可能になっている。すなわち、「userfunc1」関数は、「int」型の引数を一つとり、「int」型の値を返す関数であるが、「userfunc2」関数は、「double」型の引数を二つとり、「double」型の値を返す関数である。
また、第二の実施例では、後述するとおり、「rpc」関数はテンプレート関数として実現されているが、コンパイラがデータ型を推論することが可能なため、呼び出し時に「rpc<int, int>」のようにデータ型を指定する必要は無い。
次に、図10から図13を用いてクライアントライブラリを説明する。図10及び図11はユーザ関数の引数の数が一つの場合の定義を示し、図12及び図13はユーザ関数の引数の数が二つの場合の定義を示す。
このように、第二の実施例では、ユーザ関数の引数の数に応じて、関数の定義が複数用意される。ここでは引数の数が二つまでを示すが、それ以上の引数の数に対応するためには、単純に引数の数を増やした定義が追加されれば良い。
図10および図12はラッパ関数である「wrapper」の定義である。図11および図13は「rpc」関数の定義である。
まず、図10の「wrapper」関数について説明する。「wrapper」関数はテンプレート関数として定義されている。図10の例は、ユーザ関数の引数の数が一つの場合の定義を示すため、テンプレート引数として、ユーザ関数の返り値のデータ型「R」と、引数のデータ型「T1」が指定されている。
「wrapper」関数の引数は、ユーザ関数のシンボル名が設定される「symbol」、「dlopen」関数によって得られるハンドルが設定される「handle」、シリアライズされた引数である「input」、シリアライズされた返り値である「output」である。シリアライズされた返り値は、「wrapper」関数の中で作成され、呼び出し元に返されるため、「output」はポインタ引数である。
第二の実施例では、Boostと呼ばれるライブラリ群により提供されるシリアライズライブラリを用いてシリアライズ機能が実現される例を説明する(ライブラリのバージョン1.35を元に説明する)。
変数「input」の型は「binary_iarchive」であり、変数「output」の型は「binary_oarchive」であり、これらは、Boostのシリアライズライブラリが提供しているデータ型である。「binary_iarchive」型変数は、シリアライズされたデータをデシリアライズするために、「binary_oarchive」型変数は、変数をシリアライズするために用いられる。
「wrapper」関数の中では、まず、ユーザ関数の型が「typedef」を用いて「functype」として定義される。図10の例では、「functype」は、「T1」型の引数を取り、「R」型を返り値とする型として定義される。そして、ユーザ関数のシンボル名が設定される「symbol」と、「dlopen」関数によって得られるハンドルが設定される「handle」とを引数として「dlsym」関数が呼び出されることで、ユーザ関数ポインタが取得される。これが「functype」型にキャストされ、変数「f」に代入される。
更に、引数のデータ型である「T1」型の変数「a1」、及び、返り値のデータ型である「R」型の変数「ret」が定義される。そして、引数である変数「input」がデシリアライズされたデータが、変数「a1」に代入される。Boostのシリアライズライブラリでは、このデシリアライズ操作は「>>」として定義されている。
続いて、変数「a1」を引数としてユーザ関数「f」が実行され、返り値が変数「ret」に保存される。返り値となる変数「output」には、変数「ret」がシリアライズされたデータが入力される。このシリアライズ操作はBoostのシリアライズライブラリでは「<<」として定義されている。
次に、図11を参照して、「rpc」関数について説明する。「rpc」関数もテンプレート関数として定義されている。図11の例は、ユーザ関数の引数の数が一つの場合の定義を示すため、テンプレート引数として、ユーザ関数の返り値のデータ型「R」と引数のデータ型「T1」が指定されている。
「rpc」関数の引数は、第一の実施例の場合と同様であるが、「rpc」関数がテンプレート関数として定義されているため、引数のデータ型に制約は無い。「rpc」関数の中では、まず、ラッパ関数ポインタが取得される。このとき、テンプレート引数として与えられたデータ型が、「wrapper<R,T1>」と指定されることで、そのデータ型に応じたラッパ関数ポインタが取得される。コンパイラは、このラッパ関数ポインタが取得された時点で、テンプレート引数「R, T1」に応じた「wrapper」関数の定義を作成する。
次に、上記で得られたラッパ関数のシンボル名が取得される。これには第一の実施例で用いた「get_symbol」関数が利用される。次に、「rpc」関数の引数として与えられたユーザ関数ポインタを引数として「get_symbol」関数を呼び出すことで、ユーザ関数シンボル名が取得される。
そして、引数「a1」がシリアライズされる。Boostのシリアライズライブラリでは、シリアライズした結果を「string」型として受け取る場合、標準ライブラリの「ostringstream」型の変数を引数として、「binary_oarchive」型の変数が定義される。
ここでは、「ostringstream」型の変数「os」が定義され、それを用いて「binary_oarchive」型の変数「input」が定義されている。そして、上述と同様、「<<」を用いて引数「a1」がシリアライズされる。
次に、「rpc」関数は、「connect_to_server」関数を用いてサーバに接続する。この「connect_to_server」関数」により得られたソケットのファイルディスクリプタを引数として「write_to_socket」関数に与えることにより、ユーザ関数シンボル名が送信される。
次に、シリアライズされた引数が送信される。シリアライズされた結果は、「ostringstream」型変数「os」に設定されているので、「str()」メンバ関数でまず「string」型として取り出され、さらに、「c_str()」メンバ変数で「char」型のポインタとして取り出される。
シリアライズされた結果のサイズは、それを「string」型として取り出して、「length()」メンバ関数を呼び出すことにより得ることができる。続いて、ラッパ関数シンボル名が送信される。その後、シリアライズされた返り値が「read_from_socket」関数で取得される。
この取得されたデータをデシリアライズするため、そのデータを「string」型に変換したものを引数として用いて標準ライブラリの「istringstream」型の変数「is」が定義される。そして、変数「is」を引数として用いて、「binary_iarchive」型の変数「output」が定義される。
返り値を保存する変数「ret」が定義され、上述と同様に、「>>」を用いて変数「output」をデシリアライズしたデータが変数「ret」に設定される。最終的に、「close_connection」関数によりサーバとの接続がクローズされ、返り値「ret」がユーザプログラムに返される。
図12および図13はユーザ関数の引数の数が二つの場合の定義を示す。以下、図12の「wrapper」関数について、図10で示されたユーザ関数の引数の数が一つの場合の定義との違いを中心に説明する。この場合、テンプレート引数は、返り値1つと引数2つとの合計3つになる。
また、ユーザ関数の型において、引数の数が異なっている。これにより、引数のデシリアライズが2引数分になり、ユーザ関数も、2つの引数を用いて、呼び出されている。関数の名前は「wrapper」であり、図10で示された引数が一つの場合と同じであるが、C++において、これは許されている。
次に、図13の「rpc」関数について、図11で示されたユーザ関数の引数の数が一つの場合の定義との違いを中心に説明する。「wrapper」関数の場合と同様、テンプレート引数が返り値1つと引数2つの合計3つになる。
また、「rpc」関数自身の引数に関しても、ユーザ関数の引数が二つになるのに伴い、ユーザ関数ポインタの型が変更になり、またユーザ関数の引数が追加されている。「wrapper」関数ポインタを取得する部分でも、テンプレート引数の数が3つになっている。そして、引数をシリアライズする部分で、二つの引数がシリアライズされている。
上述のように、図10から図12への変更及び図11から図13への変更と同様の変更を加えることによって、三つ以上の引数を持つユーザ関数についても定義を記述することが可能となる。
次に、図14を参照してサーバライブラリについて説明する。サーバライブラリは、引数の数によらず、同じものが用いられる。初期化の部分は第一の実施例と同じである。
while文の中では、まず、クライアントからの接続が「accept_connection」関数で受け付けられる。ここで得られたソケットのファイルディスクリプタを用い、クライアントからユーザ関数のシンボルと、シリアライズされた引数が取得される。続いて、「binary_iarchive」型変数を作るため、取得された引数「buf」を「string」型に変換したデータを引数として用いることにより、「istringstream」型の変数「is」が定義される。更に、この変数「is」を引数として用いることにより、「binary_iarchive」型の変数「input」が定義される。この変数「input」は、後で「wrapper」関数の引数とされる。
次に、ラッパ関数シンボル名がクライアントから取得される。これを元に、ラッパ関数ポインタが「dlsym」関数を用いて取得される。そして、「ostringstream」型の変数「os」が定義され、この変数「os」を引数に「binary_oarchive」型の変数「output」が定義される。この変数「output」は、「wrapper」関数の引数として、返り値をシリアライズした内容を受け取るために用いられる。
そして、先ほど取得した「wrapper」関数のポインタを用いて、「wrapper」関数が実行される。このとき、「wrapper」関数の引数には、ユーザ関数シンボル名(「symbol」)、「dlopen」関数によって得られたハンドル(「handle」)、シリアライズされた引数を内部に持つ、「binary_iarchive」型の変数「input」、ユーザ関数の返り値をシリアライズしたものを保存するための「binary_oarchive」型の変数「output」へのポインタが与えられる。
wrapper関数が実行されると、上述の「wrapper」関数の定義通り、引数がデシリアライズされ、ユーザ関数シンボル名からユーザ関数ポインタが取得され、デシリアライズした引数を用いてユーザ関数が実行され、返り値がシリアライズされて変数「output」に入れられる。
これにより、「wrapper」関数終了後、シリアライズされた返り値の内容がクライアントに送信される。このとき、「ostringstream」型の変数「os」から「str()」メンバ関数で「string」型のデータが取り出され、さらに「c_str()」メンバ関数で、「char」型のポインタとしてデータが取り出される。取り出されるデータのサイズは、変数「os」のメンバ関数「str()」により取り出された「string」型のデータに対して、「length()」メンバ関数を呼び出すことで得られる。これらを引数に「write_to_socket」関数を呼び出すことで、クライアントにシリアライズされた返り値の内容が送信される。
なお、本発明は本実施の形態に限定されるものではなく、その要旨を逸脱しない範囲で各種の変形を許容する。例えば、本発明は、ネットワークで結合された複数のサーバ上で並列に実行するプログラムを記述する用途に適用できる。また、ネットワークで結合された別のサーバ上の資源(ファイル等)を利用するプログラムを記述する用途にも適用可能である。
なお、当然ながら、上述した実施の形態および複数の実施例は、その内容が相反しない範囲で組み合わせることができる。また、上述した実施の形態および実施例では、各部のプログラムなどを具体的に説明したが、そのプログラムなどは本願発明の要旨を逸脱しない範囲で各種に変更することができる。
この出願は、2010年6月17日に出願された日本出願特願2010−138398号を基礎とする優先権を主張し、その開示の全てをここに取り込む。

Claims (9)

  1. クライアントとサーバとが相互通信するデータ処理システムであって、
    前記クライアントは、
    ユーザプログラムに含まれるユーザ関数へのポインタが指すオブジェクトのユーザ関数シンボル名を取得するユーザ関数シンボル名取得部と、
    テンプレート関数として定義され、かつ、その内部で前記ユーザ関数を実行するラッパ関数へのポインタを、前記ユーザ関数の引数及び戻り値の型をテンプレート引数として指定することにより、取得するラッパ関数ポインタ取得部と、
    前記ラッパ関数へのポインタを用いて、前記ラッパ関数のラッパ関数シンボル名を取得するラッパ関数シンボル名取得部と、を有し、
    前記サーバは、
    前記ユーザ関数シンボル名、前記ユーザ関数の引数に対応するデータ、前記ラッパ関数シンボル名、及び、前記ユーザプログラム及び前記ラッパ関数が共有ライブラリとしてコンパイルされた共有ライブラリ化ユーザプログラムを前記クライアントから取得する通信部と、
    前記通信部により取得された前記ラッパ関数シンボル名を用いて前記ラッパ関数へのポインタを取得するラッパ関数ポインタ取得部と、
    前記通信部により取得された前記ユーザ関数シンボル名及び前記ユーザ関数の引数に対応するデータを引数として、前記ラッパ関数へのポインタで特定される、前記共有ライブラリ化ユーザプログラム内の前記ラッパ関数を実行するラッパ関数実行部と、
    を有するデータ処理システム。
  2. 前記通信部は、前記ユーザ関数の引数に対応するデータとして、シリアライズされた引数データを前記クライアントから取得し、
    前記ラッパ関数実行部は、前記ラッパ関数の実行に伴い実行されるユーザ関数ポインタ取得部及びユーザ関数実行部を含み、
    前記ユーザ関数ポインタ取得部は、前記通信部により取得された共有ライブラリ化ユーザプログラム及び前記ユーザ関数シンボル名に基づいて、呼び出すべきユーザ関数へのユーザ関数ポインタを取得し、
    前記ユーザ関数実行部は、前記通信部で取得されたシリアライズされた引数データから前記ユーザ関数の引数を復元し、前記ユーザ関数ポインタと、当該復元された引数とを用いて、前記ユーザ関数を実行する、
    請求項1に記載のデータ処理システム。
  3. ユーザプログラムに含まれるユーザ関数へのポインタが指すオブジェクトのユーザ関数シンボル名を取得するユーザ関数シンボル名取得部と、
    テンプレート関数として定義され、かつ、その内部で前記ユーザ関数を実行するラッパ関数へのポインタを、前記ユーザ関数の引数及び戻り値の型をテンプレート引数として指定することにより、取得するラッパ関数ポインタ取得部と、
    前記ラッパ関数へのポインタを用いて、前記ラッパ関数のラッパ関数シンボル名を取得するラッパ関数シンボル名取得部と、
    前記ユーザ関数シンボル名、前記ユーザ関数の引数に対応するデータ、前記ラッパ関数シンボル名、及び、前記ユーザプログラム及び前記ラッパ関数が共有ライブラリとしてコンパイルされた共有ライブラリ化ユーザプログラムを他のコンピュータ装置へ送信する通信部と、
    を有するコンピュータ装置。
  4. ユーザプログラム、及び、テンプレート関数として定義され、かつ、その内部で当該ユーザプログラムに含まれるユーザ関数を実行するラッパ関数が、共有ライブラリとしてコンパイルされた共有ライブラリ化ユーザプログラム、ユーザ関数シンボル名、ユーザ関数の引数に対応するデータ、及び、ラッパ関数シンボル名を他のコンピュータ装置から取得する通信部と、
    前記通信部により取得された前記ラッパ関数シンボル名を用いて前記ラッパ関数へのポインタを取得するラッパ関数ポインタ取得部と、
    前記通信部により取得された前記ユーザ関数シンボル名及び前記ユーザ関数の引数に対応するデータを引数として、前記ラッパ関数へのポインタで特定される、前記共有ライブラリ化ユーザプログラム内の前記ラッパ関数を実行するラッパ関数実行部と、
    を有するコンピュータ装置。
  5. 前記通信部は、前記ユーザ関数の引数に対応するデータとして、シリアライズされた引数データを前記他のコンピュータ装置から取得し、
    前記ラッパ関数実行部は、前記ラッパ関数が実行されると起動されるユーザ関数ポインタ取得部及びユーザ関数実行部を含み、
    前記ユーザ関数ポインタ取得部は、前記通信部により取得された共有ライブラリ化ユーザプログラム及び前記ユーザ関数シンボル名に基づいて、呼び出すべきユーザ関数へのユーザ関数ポインタを取得し、
    前記ユーザ関数実行部は、前記通信部で取得されたシリアライズされた引数データから前記ユーザ関数の引数を復元し、前記ユーザ関数ポインタと、当該復元された引数とを用いて、前記ユーザ関数を実行する、
    請求項4に記載のコンピュータ装置。
  6. 相互通信するクライアントとサーバとにより実行されるプログラムであって、
    前記クライアントに、
    ユーザプログラムに含まれるユーザ関数へのポインタが指すオブジェクトのユーザ関数シンボル名を取得するユーザ関数シンボル名取得部と、
    テンプレート関数として定義され、かつ、その内部で前記ユーザ関数を実行するラッパ関数へのポインタを、前記ユーザ関数の引数及び戻り値の型をテンプレート引数として指定することにより、取得するラッパ関数ポインタ取得部と、
    前記ラッパ関数へのポインタを用いて、前記ラッパ関数のラッパ関数シンボル名を取得するラッパ関数シンボル名取得部と、
    を実現させ、
    前記サーバに、
    前記ユーザ関数シンボル名、前記ユーザ関数の引数に対応するデータ、前記ラッパ関数シンボル名、及び、前記ユーザプログラム及び前記ラッパ関数が共有ライブラリとしてコンパイルされた共有ライブラリ化ユーザプログラムを前記クライアントから取得する通信部と、
    前記通信部により取得された前記ラッパ関数シンボル名を用いて前記ラッパ関数へのポインタを取得するラッパ関数ポインタ取得部と、
    前記通信部により取得された前記ユーザ関数シンボル名及び前記ユーザ関数の引数に対応するデータを引数として、前記ラッパ関数へのポインタで特定される、前記共有ライブラリ化ユーザプログラム内の前記ラッパ関数を実行するラッパ関数実行部と、
    を実現させるプログラム。
  7. 前記サーバで実現される前記通信部は、前記ユーザ関数の引数に対応するデータとして、シリアライズされた引数データを前記クライアントから取得し、
    前記サーバで実現される前記ラッパ関数実行部は、前記ラッパ関数が実行されると起動されるユーザ関数ポインタ取得部及びユーザ関数実行部を含み、
    前記ユーザ関数ポインタ取得部は、前記通信部により取得された共有ライブラリ化ユーザプログラム及び前記ユーザ関数シンボル名に基づいて、呼び出すべきユーザ関数へのユーザ関数ポインタを取得し、
    前記ユーザ関数実行部は、前記通信部で取得されたシリアライズされた引数データから前記ユーザ関数の引数を復元し、前記ユーザ関数ポインタと、当該復元された引数とを用いて、前記ユーザ関数を実行する、
    請求項6に記載のプログラム。
  8. 相互通信するクライアントとサーバとにより実行されるデータ処理方法であって、
    前記クライアントが、
    ユーザプログラムに含まれるユーザ関数へのポインタが指すオブジェクトのユーザ関数シンボル名を取得し、
    テンプレート関数として定義され、かつ、その内部で前記ユーザ関数を実行するラッパ関数へのポインタを、前記ユーザ関数の引数及び戻り値の型をテンプレート引数として指定することにより、取得し、
    前記ラッパ関数へのポインタを用いて、前記ラッパ関数のラッパ関数シンボル名を取得し、
    前記サーバが、
    前記ユーザ関数シンボル名、前記ユーザ関数の引数に対応するデータ、前記ラッパ関数シンボル名、及び、前記ユーザプログラム及び前記ラッパ関数が共有ライブラリとしてコンパイルされた共有ライブラリ化ユーザプログラムを前記クライアントから取得し、
    前記ラッパ関数シンボル名を用いて前記ラッパ関数へのポインタを取得し、
    前記ユーザ関数シンボル名及び前記ユーザ関数の引数に対応するデータを引数として、前記ラッパ関数へのポインタで特定される、前記共有ライブラリ化ユーザプログラム内の前記ラッパ関数を実行する、
    データ処理方法。
  9. 前記ユーザ関数の引数に対応するデータは、シリアライズされた引数データであり、
    前記ラッパ関数の実行は、
    前記共有ライブラリ化ユーザプログラム及び前記ユーザ関数シンボル名に基づいて、呼び出すべきユーザ関数へのユーザ関数ポインタを取得すること、
    前記シリアライズされた引数データから前記ユーザ関数の引数を復元すること、
    前記ユーザ関数ポインタと、前記復元された引数とを用いて、前記ユーザ関数を実行することを、含む、
    請求項8に記載のデータ処理方法。
JP2012520284A 2010-06-17 2011-06-10 データ処理システム及びデータ処理方法 Active JP5811088B2 (ja)

Priority Applications (1)

Application Number Priority Date Filing Date Title
JP2012520284A JP5811088B2 (ja) 2010-06-17 2011-06-10 データ処理システム及びデータ処理方法

Applications Claiming Priority (4)

Application Number Priority Date Filing Date Title
JP2010138398 2010-06-17
JP2010138398 2010-06-17
JP2012520284A JP5811088B2 (ja) 2010-06-17 2011-06-10 データ処理システム及びデータ処理方法
PCT/JP2011/003314 WO2011158478A1 (ja) 2010-06-17 2011-06-10 データ処理システム及びデータ処理方法

Publications (2)

Publication Number Publication Date
JPWO2011158478A1 true JPWO2011158478A1 (ja) 2013-08-19
JP5811088B2 JP5811088B2 (ja) 2015-11-11

Family

ID=45347894

Family Applications (1)

Application Number Title Priority Date Filing Date
JP2012520284A Active JP5811088B2 (ja) 2010-06-17 2011-06-10 データ処理システム及びデータ処理方法

Country Status (3)

Country Link
US (1) US9116855B2 (ja)
JP (1) JP5811088B2 (ja)
WO (1) WO2011158478A1 (ja)

Families Citing this family (7)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
US9032419B2 (en) * 2011-12-16 2015-05-12 Sap Se Application function library framework
WO2015015574A1 (ja) 2013-07-30 2015-02-05 富士通株式会社 処理プログラム、処理システムおよび処理方法
US9646091B2 (en) * 2014-02-24 2017-05-09 Futurewei Technologies, Inc. File joining on back end device
US10552240B2 (en) * 2014-09-04 2020-02-04 International Business Machines Corporation Automatically generating efficient remote procedure call (RPC) code for heterogeneous systems
CN106886465B (zh) * 2015-12-16 2021-06-15 菜鸟智能物流控股有限公司 一种数据获取方法及装置
US10310872B2 (en) * 2017-02-21 2019-06-04 Red Hat, Inc. Transparent fast application launcher
JPWO2023053454A1 (ja) * 2021-10-01 2023-04-06

Family Cites Families (5)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
US6157960A (en) * 1997-05-07 2000-12-05 International Business Machines Corporation Technique for programmatically creating distributed object programs
JPH11338704A (ja) * 1998-05-25 1999-12-10 Casio Comput Co Ltd ネットワークコンピュータシステム及び記憶媒体
JP2001337935A (ja) * 2000-05-24 2001-12-07 Nec Corp 分散オブジェクト環境におけるアプリケーションのラッピング方法、その通信管理装置及び記録媒体
JP4042527B2 (ja) 2002-10-29 2008-02-06 株式会社日立製作所 呼出規約変換処理の生成方法
US7496932B2 (en) * 2004-01-12 2009-02-24 International Business Machines Corporation Communicating with remote objects in a data processing network

Also Published As

Publication number Publication date
US20130091203A1 (en) 2013-04-11
WO2011158478A1 (ja) 2011-12-22
US9116855B2 (en) 2015-08-25
JP5811088B2 (ja) 2015-11-11

Similar Documents

Publication Publication Date Title
Burns et al. Kubernetes: up and running
JP5811088B2 (ja) データ処理システム及びデータ処理方法
JP4489483B2 (ja) 初期タイプの初期オブジェクトを最終タイプの最終オブジェクトに変形する方法
US10817284B2 (en) Melding of mediation flow service component architecture (SCA) components
JP2011515741A (ja) 非同期メソッドのための宣言型サポート
Chan et al. User’s guide for mpe extensions for mpi programs
Kiraly et al. Analysing RPC and testing the performance of solutions
CN115390846A (zh) 编译构建方法、装置、电子设备和存储介质
US9720660B2 (en) Binary interface instrumentation
JP2016186697A (ja) 関数間変数共有方法及び機構
JP5409529B2 (ja) アプリケーション実行装置及びプログラム
JP7271957B2 (ja) 動的リンク装置、動的ロード装置、計算機システム、動的リンク方法、動的ロード方法、動的リンクプログラム、および動的ロードプログラム
Ogel et al. Supporting efficient dynamic aspects through reflection and dynamic compilation
Aleksyuk et al. Automated Cross-Language Integration Based on Formal Model of Components
CN118051262A (zh) 指令转换方法、装置、计算机设备及存储介质
CN117130591A (zh) 一种代码生成方法、系统及相关设备
CN117493610A (zh) 基于java实现的GraphQL参数生成方法和系统
Lavieri Mastering Java 11: Develop modular and secure Java applications using concurrency and advanced JDK libraries
Zhao et al. Svar: A Tiny C++ Header Brings Unified Interface for Multiple programming Languages
CN116383063A (zh) 模拟数据生成方法、装置、计算机存储介质及电子设备
CN117608562A (zh) 一种可执行程序生成方法、装置、电子设备及存储介质
JP2010108076A (ja) ソースコード変換方法、サーバシステム、およびサーバプログラム
Burshteyn The distributed Language Hello White Paper
Chye et al. T-Kernel Integrated Development Environment (IDE) for Seamless Middleware Development
Ou . NET High Performance Computing

Legal Events

Date Code Title Description
A621 Written request for application examination

Free format text: JAPANESE INTERMEDIATE CODE: A621

Effective date: 20140514

A131 Notification of reasons for refusal

Free format text: JAPANESE INTERMEDIATE CODE: A131

Effective date: 20150602

A521 Request for written amendment filed

Free format text: JAPANESE INTERMEDIATE CODE: A523

Effective date: 20150729

TRDD Decision of grant or rejection written
A01 Written decision to grant a patent or to grant a registration (utility model)

Free format text: JAPANESE INTERMEDIATE CODE: A01

Effective date: 20150818

A61 First payment of annual fees (during grant procedure)

Free format text: JAPANESE INTERMEDIATE CODE: A61

Effective date: 20150831

R150 Certificate of patent or registration of utility model

Ref document number: 5811088

Country of ref document: JP

Free format text: JAPANESE INTERMEDIATE CODE: R150