AsyncLock内のロックがスレッドをブロックしないのはなぜですか?

astef

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]

編集
0

コメントを追加

0

関連記事

BackgroundService.ExecuteAsync内のブロック呼び出しがメインスレッドをブロックしないのはなぜですか?

スレッドがJavaFXUIスレッドをブロックしているのはなぜですか?

RunLoopがスレッド全体の実行をブロックしないのはなぜですか?

Pythonスレッド。スレッドが互いにブロックしているのはなぜですか?

vkAcquireNextImageKHR()がスレッドをブロックしないのはなぜですか?

QTimer :: singleShotが時間1でメインスレッドをブロックするのに、0ではブロックしないのはなぜですか

joinがメインスレッドをブロックするのに、ループでブロックしないのはなぜですか?

Futureがメインスレッドをブロックしているのはなぜですか?

GoのLockOSThreadがこのOSスレッドをロックしないのはなぜですか?

asyncio.StreamReader.read returnがスレッドをブロックしなかったのはなぜですか?

メインスレッドのLooper.loop()がUIスレッドをブロックしないのはなぜですか?

1つのスレッドがCでブロックする場合、プロセス全体がブロックされないのはなぜですか

スレッドがデッド/ブロックされているのはなぜですか?

スレッドとタスクのロジックの終了時間が等しいのはなぜですか?

プロデューサースレッドがタスクを完了しないのはなぜですか?

WindowsデスクトップがUDPをブロードキャストしないのはなぜですか?

このデーモンスレッドがブロックされているのはなぜですか?

スレッドマクロ内で無名関数を使用できないのはなぜですか?

'await'がkotlinのスレッドをブロックするのはなぜですか?

UI以外のスレッドがUIをブロックするのはなぜですか?

ComputeHash()が非同期タスクでUIスレッドをブロックしているのはなぜですか?

IProgress <T> Report(T)メソッドがUIスレッドをブロックしているのはなぜですか?

セマフォが2番目のスレッドをブロックしないのはなぜですか?(C)

常にアニメーション化されているUIActivityIndicatorがメインスレッドをブロックしないのはなぜですか?

ブロック要素内の画像が高さを厳密に尊重しないのはなぜですか:0

クロムでもフレックスボックスが機能しないのはなぜですか?

スレッドがオブジェクトをローカルにキャッシュしないのはなぜですか?

pipe.writeがスレッドをブロックするのはなぜですか?

File.ReadAllLinesAsync()がUIスレッドをブロックするのはなぜですか?

TOP 一覧

  1. 1

    セレンのモデルダイアログからテキストを抽出するにはどうすればよいですか?

  2. 2

    CSSのみを使用して三角形のアニメーションを作成する方法

  3. 3

    ZScalerと証明書の問題により、Dockerを使用できません

  4. 4

    ドロップダウンリストで選択したアイテムのQComboBoxスタイル

  5. 5

    別のホストからTomcat Managerアプリにアクセスする

  6. 6

    PyCharmリモートインタープリターはプロジェクトタブにサイトパッケージのコンテンツを表示しません

  7. 7

    Windows 10でのUSB入力デバイスの挿入/取り外しの検出

  8. 8

    Python / SciPyのピーク検出アルゴリズム

  9. 9

    MLでのデータ前処理の背後にある直感

  10. 10

    useRefに反応してコンポーネントをスクロールして表示する

  11. 11

    モーダルダイアログを自動的に閉じる-サーバーコードが完了したら、Googleスプレッドシートのダイアログを閉じます

  12. 12

    パンダは異なる名前の列に追加します

  13. 13

    PictureBoxで画像のブレンドを無効にする

  14. 14

    Windows 10 Pro 1709を1803、1809、または1903に更新しますか?

  15. 15

    Pythonを使用して、リストからデータを読み取り、特定の値をElasticsearchにインデックス付けするにはどうすればよいですか?

  16. 16

    LinuxでPySide2(Qt for Python)をインストールするQt Designerはどこにありますか?

  17. 17

    Material-UIでTextFieldエラーの色を条件付きでオーバーライドする方法

  18. 18

    goormIDEは、ターミナルがロードするデフォルトプロジェクトを変更します

  19. 19

    MatplotlibまたはSeabornを使用して、グループ化されたデータから複数のプロットを生成するにはどうすればよいですか?

  20. 20

    Luaの文字列から特定の特殊文字を削除するにはどうすればよいですか?

  21. 21

    Flutterにファイルピッカープラグインを追加するにはどうすればよいですか?

ホットタグ

アーカイブ