AsyncLockがどのように機能するかを理解しようとしています。
まず、実際に機能することを証明するスニペットを次に示します。
var l = new AsyncLock();
var tasks = new List<Task>();
while (true)
{
Console.ReadLine();
var i = tasks.Count + 1;
tasks.Add(Task.Run(async () =>
{
Console.WriteLine($"[{i}] Acquiring lock ...");
using (await l.LockAsync())
{
Console.WriteLine($"[{i}] Lock acquired");
await Task.Delay(-1);
}
}));
}
「動作する」とは、(Enterキーを押して)必要な数のタスクを実行でき、スレッドの数が増えないことを意味します。従来のlock
スレッドに置き換えると、新しいスレッドが開始されたことがわかります。これは、回避しようとしていることです。
しかし、ソースコードで最初に目にするのは...ロックです
誰かがこれがどのように機能するのか、なぜそれがブロックされないのか、そして私がここで何が欠けているのかを私に説明できますか?
誰かがこれがどのように機能するのか、なぜそれがブロックされないのか、そして私がここで何が欠けているのかを私に説明できますか?
簡単に言うと、これlock
はスレッドの安全性を保証するために使用される単なる内部メカニズムです。lock
どのような方法で露出していない、と時間の任意の実際の量のためにそのロックを保持するために、任意のスレッドのための方法はありませんありません。このように、これはさまざまな並行コレクションによって内部的に使用されるロックに似ています。
ロックフリープログラミングを使用する別のアプローチがありますが、ロックフリープログラミングは、書き込み、読み取り、および保守が非常に難しいことがわかりました。この良い例(残念ながらオンラインではありません)は、90年代後半のドブ博士の記事の束でした。それぞれがより良いロックフリーキューの実装で最後をしのぐことを試みました。それらはすべて欠陥があることが判明しました-場合によっては、バグを見つけるのに10年以上かかりました。
私自身のコードでは、コードの正確さが自明である場合を除いて、ロックフリープログラミングを使用していません。
非同期ロックとロックの概念については、これを説明することに挑戦します。非同期調整プリミティブを操作するときにのみ感じたような気がします。それは私がブログ記事を書くことについてよく考えたものですが、私はそれを理解できるようにするための正しい言葉を持っていません。そうは言っても、ここに行きます...
非同期調整プリミティブは、通常の調整プリミティブとは完全に異なる平面に存在します。同期プリミティブは、スレッドとシグナルスレッドをブロックします。非同期プリミティブは、プレーンオブジェクトでのみ機能します。ブロッキングまたはシグナリングは「慣例による」だけです。
したがって、通常のlock
場合、呼び出し元のコードはすぐにロックを取得する必要があります。しかし、非同期の「ロック」では、試行されるロックは単なる要求であり、単なるオブジェクトです。呼び出し元のコードはそれをする必要さえありませんawait
。複数のロックを要求し、await
それらをすべて一緒に要求することができTask.WhenAll
ます。または、それらを他のものと組み合わせることもできます。コードは、(a)2つのロックが両方とも解放されるのを待つか、シグナル(のようなAsyncManualResetEvent
)が送信されるのを待ってから、シグナルが最初に着信した場合にロック要求をキャンセルするなどのクレイジーなことを行うことができます。
スレッドの観点からは、ユーザーモードのスレッドスケジューリングのようなものです。(プリエンプティブではなく)協調マルチタスクとの類似点もいくつかあります。しかし、全体として、非同期プリミティブは別の平面に「リフト」され、スレッドではなく、オブジェクトとコードのブロックでのみ機能します。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加