HOME»応用情報技術者試験掲示板»再帰的、再入可能や再配置可能のイメージ
投稿する
実際に言葉にして説明すると難しいですが、再帰自体は言語学から論理学に至るまでプログラミング(計算機科学)以外でも使われる概念なので、まあ・・・プログラムを作る上で自己参照が必要になったら出てくる概念、くらいでいいです。
じゃあ、そんな機会がいつ出てくるんだよ、っていうと、昔Javaで
どんな階層になるかわからないがZipで固めたい
という依頼がありました。
JavaのZipライブラリは、結局ファイルパスを投げ込まないとならないので、ひたすらディレクトリ階層がでなくなるまで掘っていって(再帰の終了条件をディレクトリファイルの不存在にした)ファイルパスを集めてくるというのを再帰で書いたことがあります。C#とかのZipライブラリは頭がいいからそのあたりは自分でやってくれるけど、Javaは気が利かなかったんですよね。
プログラム書いてないと想像しろっつっても難しいところはあります。
保存場所ではなく、配置場所でしょうか?
現代のOSの基本的な仕組みとしてプログラムはメモリ上のどこに配置されても
動作します。
配置されるのはプログラムの本体(具体的にはテキスト領域)です。
再配置可能なプログラムは
・コンパイル時に相対アドレスで作成され
・実行時にOSで仮想記憶上に配置されます
現代のプログラムはほぼすべてこのようになっています。
これ以上となるとOSのメモリ管理の知識が必要となり、かなり複雑になります。
詳細を知りたい場合はLinuxの仮想メモリの管理方法を調べてみてください。
https://www.ap-siken.com/kakomon/29_haru/q7.html
プログラムは主記憶上にロードされ,命令が格納されたアドレスを指定して実行します。
そのプログラムをコンパイルした結果が,
・1000番地の命令を実行
・1002番地の命令を実行
・1004番地の命令を実行
のように絶対番地指定であったなら,そのプログラムは1000番地にしか配置できません。
ロード開始番地は必ず1000なので,このプログラムを複数,主記憶にロードすることもできません。
再配置可能なプログラムは,基底レジスタ(BR,ベースレジスタ)を用いて,
・BR+0番地の命令を実行
・BR+2番地の命令を実行
・BR+4番地の命令を実行
のようにプログラムをコンパイルします。そして,
タスクAの実行時は BR=1000番地
タスクBの実行時は BR=2000番地
とすることで,同じプログラムを複数,主記憶にロード可能にします。これが再配置可能です。
仮想記憶云々まで話題を拡張せずに,もっとも単純な再配置可能のイメージを伝えるならこうなるでしょう。
再帰的、再入可能や再配置可能のイメージ [4065]
八王子さん(No.1)
再帰的、再入可能や再配置可能などの関係性や具体的なイメージが全く分かりません。
再帰的は自身を呼び出せるもの。呼び出された変数達がそれぞれ独立したものでないとプログラムが回らない、だからどこから呼び出されてもそれぞれの変数は共有されず個別に値を返す再入可能という性質もある。
…くらいの理解度はありますが、正直丸暗記状態です。そもそもこれはオブジェクト指向みたいな、プログラムを作る時の概念的な話なのですか?それとも別の何かですか?
また先の説明も丸暗記状態なので、再入可能かつ再配置可能なプログラムと言われてもイメージが全く付かず困っています。
https://www.ap-siken.com/s/kakomon/03_aki/q6.html
再帰的は自身を呼び出せるもの。呼び出された変数達がそれぞれ独立したものでないとプログラムが回らない、だからどこから呼び出されてもそれぞれの変数は共有されず個別に値を返す再入可能という性質もある。
…くらいの理解度はありますが、正直丸暗記状態です。そもそもこれはオブジェクト指向みたいな、プログラムを作る時の概念的な話なのですか?それとも別の何かですか?
また先の説明も丸暗記状態なので、再入可能かつ再配置可能なプログラムと言われてもイメージが全く付かず困っています。
https://www.ap-siken.com/s/kakomon/03_aki/q6.html
2023.03.20 23:29
pixさん(No.2)
★AP シルバーマイスター
コンピュータの動作におけるかなり低レベル(OS、プログラミング)の概念です。
以下にそれぞれの一例を挙げます。
再帰的:プログラミングの概念
関数が自分自身を呼び出す
古い時代の言語、特にC言語などで利用される
※関数型言語でも用いられる
再入可能:共有ライブラリ(DLL)などの概念
メモリ上にロードされたライブラリを複数のプロセスで共有しあう
個別の変数はプロセス側で管理される
再配置可能:OSのプロセスの概念
プロセスをメモリ上に展開するときに、メモリのどの場所に配置しても
動くようにする
そのために、プログラム内部のアドレスは絶対指定ではなく相対指定する
ように作成されている
具体的にイメージするにはOSの基本的な内部構造を理解している必要があります。
以下にそれぞれの一例を挙げます。
再帰的:プログラミングの概念
関数が自分自身を呼び出す
古い時代の言語、特にC言語などで利用される
※関数型言語でも用いられる
再入可能:共有ライブラリ(DLL)などの概念
メモリ上にロードされたライブラリを複数のプロセスで共有しあう
個別の変数はプロセス側で管理される
再配置可能:OSのプロセスの概念
プロセスをメモリ上に展開するときに、メモリのどの場所に配置しても
動くようにする
そのために、プログラム内部のアドレスは絶対指定ではなく相対指定する
ように作成されている
具体的にイメージするにはOSの基本的な内部構造を理解している必要があります。
2023.03.20 23:56
GinSanaさん(No.3)
★AP プラチナマイスター
>そもそもこれはオブジェクト指向みたいな、プログラムを作る時の概念的な話なのですか?それとも別の何かですか?
実際に言葉にして説明すると難しいですが、再帰自体は言語学から論理学に至るまでプログラミング(計算機科学)以外でも使われる概念なので、まあ・・・プログラムを作る上で自己参照が必要になったら出てくる概念、くらいでいいです。
じゃあ、そんな機会がいつ出てくるんだよ、っていうと、昔Javaで
どんな階層になるかわからないがZipで固めたい
という依頼がありました。
JavaのZipライブラリは、結局ファイルパスを投げ込まないとならないので、ひたすらディレクトリ階層がでなくなるまで掘っていって(再帰の終了条件をディレクトリファイルの不存在にした)ファイルパスを集めてくるというのを再帰で書いたことがあります。C#とかのZipライブラリは頭がいいからそのあたりは自分でやってくれるけど、Javaは気が利かなかったんですよね。
プログラム書いてないと想像しろっつっても難しいところはあります。
2023.03.20 23:57
八王子さん(No.4)
ありがとうございます。
Pixさんの、『再配置可能はどこに置いても動くように相対パスにする』というのが引っかかりました。再配置可能のプログラムをデスクトップに置いてもprogramdataフォルダに置いても同じ挙動をさせるには、再配置可能の中身のパス指定は絶対パスじゃないとダメじゃないですか?
Ginsanaさんありがとうございます。プログラミングやってない身としてはかなり難しい内容でしたが参考になります!
Pixさんの、『再配置可能はどこに置いても動くように相対パスにする』というのが引っかかりました。再配置可能のプログラムをデスクトップに置いてもprogramdataフォルダに置いても同じ挙動をさせるには、再配置可能の中身のパス指定は絶対パスじゃないとダメじゃないですか?
Ginsanaさんありがとうございます。プログラミングやってない身としてはかなり難しい内容でしたが参考になります!
2023.03.21 07:42
Howitzerさん(No.5)
再入可能
DBに排他制御ってありますよね。(誰かが使っているから使えません的な)
再入可能はその逆で、誰かが使用中でも使えること。
使えるけれど、データは分けとかないと「ぐちゃぐちゃ」になるのは想像できると思います。
再使用可能
「再入可能」は、誰かが使用中でも使用可能だったのに対し、
「再使用可能」は、誰かが使い終わったあとに使用可能なこと。
再帰
FORTRANだと、FORTRAN77までは使えなかったけれど、
FORTRAN95からは使えるようになったので、私の認識は逆ですね。
・太古の言語:再帰が使えない
・古めの言語:再帰が使えるのが売り
・最近の言語:再帰が使えるのは当たり前
※当然例外あり
クイックソートや二分木のアルゴリズムをイメージすればよいのではないでしょうか。
「ディレクトリ階層がなくなるまで掘っていく」のは、ディレクトリ降下ですかね。
このサイトの「再帰」の解説では「複数のプロセス」となっていますが、
再帰なので「同じプロセス」ではないかと思いました。
再配置可能
文字通り、メモリマップ上の別な場所へ再配置しても問題なく動作すること。
パスはディスク上の位置なので関係ないですね。
DBに排他制御ってありますよね。(誰かが使っているから使えません的な)
再入可能はその逆で、誰かが使用中でも使えること。
使えるけれど、データは分けとかないと「ぐちゃぐちゃ」になるのは想像できると思います。
再使用可能
「再入可能」は、誰かが使用中でも使用可能だったのに対し、
「再使用可能」は、誰かが使い終わったあとに使用可能なこと。
再帰
> 古い時代の言語、特にC言語などで利用される
FORTRANだと、FORTRAN77までは使えなかったけれど、
FORTRAN95からは使えるようになったので、私の認識は逆ですね。
・太古の言語:再帰が使えない
・古めの言語:再帰が使えるのが売り
・最近の言語:再帰が使えるのは当たり前
※当然例外あり
クイックソートや二分木のアルゴリズムをイメージすればよいのではないでしょうか。
「ディレクトリ階層がなくなるまで掘っていく」のは、ディレクトリ降下ですかね。
このサイトの「再帰」の解説では「複数のプロセス」となっていますが、
再帰なので「同じプロセス」ではないかと思いました。
再配置可能
文字通り、メモリマップ上の別な場所へ再配置しても問題なく動作すること。
パスはディスク上の位置なので関係ないですね。
2023.03.21 07:55
八王子さん(No.6)
再配置可能は、ファイルの場所ではなくメモリの場所でしたか。
しかしメモリでの保存場所なんて決められるものなのですか?OSが勝手に割り振るイメージなのですが。
そもそもが理解出来ていないのですが、配置可能プログラムAがあるとして、Aの中身の何かをメモリに配置するのですか?
しかしメモリでの保存場所なんて決められるものなのですか?OSが勝手に割り振るイメージなのですが。
そもそもが理解出来ていないのですが、配置可能プログラムAがあるとして、Aの中身の何かをメモリに配置するのですか?
2023.03.21 20:56
pixさん(No.7)
★AP シルバーマイスター
>しかしメモリでの保存場所なんて決められるものなのですか?
>OSが勝手に割り振るイメージなのですが。
>そもそもが理解出来ていないのですが、配置可能プログラムAがあるとして、
>Aの中身の何かをメモリに配置するのですか?
保存場所ではなく、配置場所でしょうか?
現代のOSの基本的な仕組みとしてプログラムはメモリ上のどこに配置されても
動作します。
配置されるのはプログラムの本体(具体的にはテキスト領域)です。
再配置可能なプログラムは
・コンパイル時に相対アドレスで作成され
・実行時にOSで仮想記憶上に配置されます
現代のプログラムはほぼすべてこのようになっています。
これ以上となるとOSのメモリ管理の知識が必要となり、かなり複雑になります。
詳細を知りたい場合はLinuxの仮想メモリの管理方法を調べてみてください。
2023.03.21 21:10
Howitzerさん(No.8)
pixさん(No.7) とは別の観点で
組み込み系では、プログラムがROM上で動作する場合もあります。
そのような場合は開発者がアドレス(動作する場所)を決定できますが、
決まった場所で動作するのですから、再配置可能である必要はありません。
勝手に割り振られても動作するためには、再配置可能である必要があります。
「メモリマップ上の別な場所へ再配置しても問題なく動作すること」
がわかりにくければ、
「メモリマップ上のどこへ配置しても問題なく動作すること」
という理解でもよいと思います。
> しかしメモリでの保存場所なんて決められるものなのですか?
組み込み系では、プログラムがROM上で動作する場合もあります。
そのような場合は開発者がアドレス(動作する場所)を決定できますが、
決まった場所で動作するのですから、再配置可能である必要はありません。
> OSが勝手に割り振るイメージなのですが。
勝手に割り振られても動作するためには、再配置可能である必要があります。
「メモリマップ上の別な場所へ再配置しても問題なく動作すること」
がわかりにくければ、
「メモリマップ上のどこへ配置しても問題なく動作すること」
という理解でもよいと思います。
2023.03.22 06:56
jjon-comさん(No.9)
★AP プラチナマイスター
> リロケータブル(Relocation,再配置可能)
> プログラムを主記憶上のどの位置においても正しく実行できる特性
https://www.ap-siken.com/kakomon/29_haru/q7.html
プログラムは主記憶上にロードされ,命令が格納されたアドレスを指定して実行します。
そのプログラムをコンパイルした結果が,
・1000番地の命令を実行
・1002番地の命令を実行
・1004番地の命令を実行
のように絶対番地指定であったなら,そのプログラムは1000番地にしか配置できません。
ロード開始番地は必ず1000なので,このプログラムを複数,主記憶にロードすることもできません。
再配置可能なプログラムは,基底レジスタ(BR,ベースレジスタ)を用いて,
・BR+0番地の命令を実行
・BR+2番地の命令を実行
・BR+4番地の命令を実行
のようにプログラムをコンパイルします。そして,
タスクAの実行時は BR=1000番地
タスクBの実行時は BR=2000番地
とすることで,同じプログラムを複数,主記憶にロード可能にします。これが再配置可能です。
仮想記憶云々まで話題を拡張せずに,もっとも単純な再配置可能のイメージを伝えるならこうなるでしょう。
2023.03.22 12:55
jjon-comさん(No.10)
★AP プラチナマイスター
例えば,タスクAが次のプログラムを実行すると想定したとき,
・1000番地の命令を実行して,1800番地のデータをロード
・1002番地の命令を実行して,1802番地のデータを加算
・1004番地の命令を実行して,1804番地にデータをセーブ
タスクBも1000,1002,1004番地の命令は共有できるはずです。(命令領域は読み取りのみで,タスク実行によって命令領域を書き換えないならば)
しかし1800,1802,1804番地はタスクAが書き換えるのでタスクBと共有できません。
タスクBが主記憶にロードされたときは,
・1000番地の命令を実行して,1900番地のデータをロード
・1002番地の命令を実行して,1902番地のデータを加算
・1004番地の命令を実行して,1904番地にデータをセーブ
のように,変数領域だけをタスクB用に別途割り当てる仕組みがあれば,
タスクAとタスクBは同じ命令領域を共有し,かつ,同時実行ができます。
リエントラント(Reentrant,再入可能)
各プロセスごとに変数部分を割り当てることで、複数のプロセスで同時に実行できる性質
https://www.ap-siken.com/kakomon/17_haru/q36.html
のもっとも単純なイメージを伝えるならこうなるでしょう。
・1000番地の命令を実行して,1800番地のデータをロード
・1002番地の命令を実行して,1802番地のデータを加算
・1004番地の命令を実行して,1804番地にデータをセーブ
タスクBも1000,1002,1004番地の命令は共有できるはずです。(命令領域は読み取りのみで,タスク実行によって命令領域を書き換えないならば)
しかし1800,1802,1804番地はタスクAが書き換えるのでタスクBと共有できません。
タスクBが主記憶にロードされたときは,
・1000番地の命令を実行して,1900番地のデータをロード
・1002番地の命令を実行して,1902番地のデータを加算
・1004番地の命令を実行して,1904番地にデータをセーブ
のように,変数領域だけをタスクB用に別途割り当てる仕組みがあれば,
タスクAとタスクBは同じ命令領域を共有し,かつ,同時実行ができます。
リエントラント(Reentrant,再入可能)
各プロセスごとに変数部分を割り当てることで、複数のプロセスで同時に実行できる性質
https://www.ap-siken.com/kakomon/17_haru/q36.html
のもっとも単純なイメージを伝えるならこうなるでしょう。
2023.03.22 13:16
八王子さん(No.11)
皆様ありがとうございます。
命令の配置場所の事だったのですね。
もっと勉強して100%理解できるようにします。
命令の配置場所の事だったのですね。
もっと勉強して100%理解できるようにします。
2023.03.22 20:49