21

CI では再帰関数については知っていますが、再入可能関数については聞いたことがあります。

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

4

8 に答える 8

26

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

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

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

于 2008-11-04T09:30:40.413 に答える
16

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

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

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

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

于 2008-11-04T09:20:16.630 に答える
13

アンワインドが最初に言ったことはほとんど正しいです-マルチスレッドに限定されないことを除いて(また、グローバルデータをロックで保護すると、スレッドセーフになりますが、必ずしも再入可能ではありません) [編集] 彼はこれを説明するために投稿を修正しました :-)

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

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

于 2008-11-04T09:29:44.380 に答える
12

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

于 2008-11-04T10:33:05.657 に答える
3

はい、これ:

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

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

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

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

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

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

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

于 2008-11-24T16:57:36.210 に答える
2

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

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

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

つまり、静的変数または共有変数を含めることはできません....

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

そしてもちろん、再入可能関数は再帰関数と同じではありません..まったく異なる概念....

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

于 2012-06-05T11:16:32.040 に答える
-2

すべての再帰コードは再入可能です...しかし、すべての再入可能コードが再帰的であるとは限りません。

于 2012-01-27T19:12:57.287 に答える
-2

すべての再入可能コードは再帰ですが、すべての再帰が再入可能であるとは限りません。再帰の例は、直接または間接的に自分自身を呼び出す任意の関数です。リエントアントの例は、割り込みハンドラルーチンです。

于 2010-12-03T04:36:39.883 に答える