誰かが「リエントラント」コードと呼ぶことができるコードを教えてもらえますか?
リアルタイムオペレーティングシステムを読んでいるときに、このWordに出くわしました。コードを「再入可能」コードにするためには、どの分野に固執する必要がありますか?
一般に、コードの再入可能なブロックは、最初のアクターがコードを通過するパスに影響を与えることなく、以前の呼び出しが終了する前に別のアクターが入力できるブロックです。つまり、コードの実行中にコードを再入力しても、正しい結果が得られる可能性があります。
ほとんどの場合、「アクター」は同じプロセスのスレッドですが、スレッドセーフおよび再入可能の概念微妙に異なります。すべてのスレッドセーフブロックが再入可能であるわけではありませんが、すべての再入可能ブロックはスレッドセーフです。つまり、再入可能性はスレッドセーフよりも強力な特性です。これは、レイモンド・チェンの良い例で、コードのブロックがスレッドセーフであるが再入可能ではない可能性があることを示しています。
コードが再帰的である場合は特別な場合があります。MarcGravellが指摘しているように、同じアクターが自身の呼び出しが完了する前にコードを呼び出しています。正しい再帰ブロックはすべて再入可能です。もちろん、すべての再入可能ブロックが再帰的であるわけではありません。
ジョンフェミネラの答えは言う:
再入可能なコードブロックは、以前の呼び出しが終了する前に別のアクターが入力できるブロックです。つまり、コードの実行中にコードを再入力することができます。
しかし、それは非再入可能なコードブロックにも当てはまります。この問題に関係なくコードのブロックが記述されている場合でも、2番目のアクターが同時にそれを入力することは可能です。
問題は、これがいずれかの呼び出しの結果にどのような影響を与えるかです。より正確には、リエントラントブロックは、以前の呼び出しが終了する前に別のアクターが入力できるブロックです結果を変更せずにいずれかの呼び出し。
どちらの呼び出しも、他方の「存在」を検出できないはずです。
事実上すべての種類の再帰コードはリエントラントとして分類できます(つまり、終了せずに同じメソッドにコールバックできます)が、これはロック、ミューテックス、セマフォなどについて話すときに使用されます特に。たとえば、ロックを取得したらコードを再度正常に「ロック」できる(つまり、自分でデッドロックしない)場合、ロックは再入可能です-例:
public void AddIfNecessary(string s) {
lock(syncObj) {
if(!Contains(s)) Add(s);
}
}
public void Add(string s) {
lock(syncObj) {
list.Add(s);
}
}
public bool Contains(string s) {
lock(syncObj) {
return list.Contains(s);
}
}
ここで、ロックが再入可能であるという事実は、すでに「排他的」ロックを持っていることを心配せずにContains
とAdd
を呼び出すことができることを意味し、コードを単純化します。内部的には、単純な「使用中」フラグではなく、カウンターが使用されます。
再入可能コードは、ページが共通のリソースを共有し、リソースを変更または操作してはならない場合です。その場合、このリソースは再入可能コードまたは純粋なコードとして知られています。
並行して実行されているさまざまなスレッドから呼び出すことができるコード。したがって、コード:
最初のスレッドがコードを実行している最中に、別のスレッドがコードを呼び出すことはできますか?コードがコールバック関数に譲る場合、最初のランスルーが完了する前に、コールバック関数自体がコードを呼び出すことができますか?
コードがロックダウンされていないグローバル変数を使用している場合、または特別な予防措置を講じていない独自の静的変数を持っている場合、これらのシナリオのいずれかがコードを壊す可能性があります。
コンピュータプログラムは、実行の途中で中断され、前の呼び出しが完了する前に安全に再度呼び出される場合、再入可能と呼ばれます。割り込みは、ジャンプや呼び出しなどの内部アクション、またはハードウェア割り込みや信号などの外部アクションによって引き起こされる可能性があります。再入力された呼び出しが完了すると、前の呼び出しは正しい実行を再開します。
再入可能でない例
class Test {
int count;
// Here method1() is not reentrant
int method1()
{
return count + 1;
}
}
リエントラントの例
class Test {
int count;
// Here method1() is reentrant
int method1(int count)
{
return count + 1;
}
}
簡単に言うと、再入可能コードは、複数のプロセス間で共有できるコードです。
これは、次の条件が満たされている場合に可能です。
したがって、これらの条件に従うコードは、再入可能コードと呼ぶことができます。