web-dev-qa-db-ja.com

Cのリエントラント関数と再帰関数の違いは何ですか?

Cでは、再帰関数については知っていますが、リエントラント関数について聞いたことがあります。

それは何ですか?そして、それらの違いは何ですか?

21
Manoj Doubts

関数は、同時に複数の実行スレッドを「通過」させることをサポートしている場合、再入可能です。これは、実際のマルチスレッドが原因である可能性があります。このケースを以下で使用するか、他の投稿者が指摘している他の理由が原因です。マルチスレッドが最初に頭に浮かんだので、おそらく最も理解しやすいので、私はそのケースに焦点を合わせました。

これは、静的な「グローバル」データを使用できないことを意味します。これは、そのデータが2つ(またはそれ以上)のスレッドによって並列にアクセスされ、ひどく壊れることが多いためです。再入可能関数には、静的に格納するのではなく、呼び出し固有の状態を保持するための明示的な引数が含まれていることがよくあります。

strtok()は、よく知られているC標準ライブラリの関数の典型的なケースです。 ない 再入可能であること。

[編集]:コメントにはたくさんの洞察、説明、修正がありますので、それらも読んでください!皆さん、助けてくれてありがとう。

16
unwind

この用語の意味を理解すると、覚えやすくなります。

「再入可能」という用語は、関数がすでに実行されている間、通常は並行環境で「再入力 "」を実行しても安全であることを意味します。

つまり、2つのタスクが互いに干渉することなく関数を同時に実行できる場合、関数は再入可能です。あるタスクによる実行が別のタスクの影響に影響を与える場合、関数は再入可能ではありません。これは通常、グローバル状態またはデータが使用される場合に当てはまります。ローカル変数と引数のみを使用する関数は、通常、再入可能です。

23
user34005

関数の「再入可能」は、前の呼び出しが戻る前に呼び出されたときに発生します。これが発生する主な理由は3つあります。再帰(関数がそれ自体を呼び出す)、マルチスレッド、および割り込みです。関数が再入力されることは明らかであるため、通常、再帰はより簡単です。再入可能性は非同期であるため、マルチスレッドと割り込みはより注意が必要です。他の回答で述べられているように、ほとんどの場合、関数はグローバルデータを変更するべきではありません(グローバルデータの読み取りは問題ありません。クリティカルセクションとして保護されている場合、書き込みの一部の王は問題ありません)。

10
Daniel Quadros

巻き戻し元々が言ったことはほとんど正しいです-マルチスレッドに限定されないことを除いて(また、グローバルデータをロックで保護するとスレッドセーフになります-しかしnot必ずしも再-参加者)。 [編集]彼は今これを説明するために彼の投稿を修正しました:-)

関数は、再帰の結果として、直接または間接的に同じスレッドに再入力することもできます(つまり、関数aは関数bを呼び出し、関数cは関数aを呼び出します)。

もちろん、複数のスレッドがそれを呼び出す可能性があることに基づいて再入可能性から保護している場合は、再帰的なケースもカバーされます。ただし、その逆は当てはまりません。

10
philsquared

はい、これ:

  • 関数の各呼び出しが一意のデータを参照する場合、リエントラント関数は複数のスレッドから同時に呼び出すことができます。

  • スレッドセーフ関数は、各呼び出しが共有データを参照するときに、複数のスレッドから同時に呼び出すことができます。共有データへのすべてのアクセスはシリアル化されます。

Qtマニュアルから恥知らずに盗まれました。しかし、それは短く簡潔な定義です。基本的に、非再入可能関数もrecursion-safeではありません。

さて、recursive関数とは何ですか?これは一種の関数の定義です。再帰関数は、それ自体の観点から定義されます。彼らは入力を減らし、自分自身を呼び出し、再び自分自身を呼び出す必要なしに基本的なケースを理解できるようになるまで。

つまり、2つのことがあります。

  • 再帰関数は一種の定義です。
  • 再入可能関数は、一意のデータにアクセスするたびに、複数のスレッドがそれらを呼び出すことができることを保証する関数です。

さて、上記のマルチスレッドビークルは、同時に機能を複数回アクティブ化するという目的にのみ役立ちます。ただし、再帰関数がある場合は、またその関数を同時に複数回アクティブ化できます。そのためのほとんどの再帰関数も再入可能でなければなりません。

リエントラント関数は、マルチスレッド環境で適切に機能することを保証する関数です。つまり、関数が1つのスレッドからアクセスしている間、別のスレッドがそれを呼び出すことができます...それぞれに個別の実行スタックと処理があることを意味します...したがって、関数には、実行を害したり妨害したりする可能性のある静的変数または共有変数を含めないでください。

別のスレッドから安全に実行しながら、スレッドから呼び出すことができる平均関数......そして適切に....私が正しいことに答えたことを願っています....

そしてもちろん、リエントラント関数は再帰関数と同じではありません....まったく異なる概念....リエントラント関数は、マルチスレッド環境でうまく機能することを保証する関数です。つまり、関数が1つのスレッドからアクセスしている間、別のスレッドがそれを呼び出すことができます...それぞれに個別の実行スタックと処理があることを意味します...したがって、関数には、実行を害したり妨害したりする可能性のある静的変数または共有変数を含めないでください。

つまり、静的変数または共有変数を含めるべきではありません。

別のスレッドから安全に実行しながら、スレッドから呼び出すことができる平均関数......そして適切に....私が正しいことに答えたことを願っています....

そしてもちろん、リエントラント関数は再帰関数と同じではありません....まったく異なる概念....

続きを読む: http://wiki.answers.com/Q/What_is_a_reentrant_function#ixzz1wut38jLF Wiki: http://en.wikipedia.org/wiki/Reentrancy_%28computing%29 ==

1
kapilddit