ロックを使用している場合でも、アルゴリズムにロックは不要ですか?


9

ロックフリーの一般的な定義は、少なくとも1つのプロセスが進行することです。1

キューなどの単純なデータ構造があり、ロックで保護されている場合、1つのプロセスがロックを取得し、必要な処理を実行して解放できるため、1つのプロセスは常に進行できます。

それでは、ロックフリーの定義を満たしていますか?


1たとえば、M。Herlihy、V。Luchangco、M。Moirを参照してください。障害物のない同期:例として両終端キュー。分散コンピューティング、2003年。「一部のスレッドが常に進行することのみを保証する場合、ロックフリーです」。


3
データ構造と、ロックを使用しないアルゴリズムのセットを説明するために、「ロックフリー」を常に理解してきました。アトミックメモリ操作の小さな定義されたセットだけです。例えばdrdobbs.com/parallel/writing-lock-free-code-a-corrected-queue/...
ポール・ジョンソン

回答:


16

それはロックフリーの定義ではありません。

進捗を保証できる場合は、デッドロック発生せず、すべての要求が最終的に完了した場合は、飢餓発生しませんが、ロックは発生しません。

とにかく、あなたの簡単な例が実際にこれを提供しているかどうかを質問します。複数のロックが関係する場合に実際に進捗を保証するには、ロック階層などが必要です。


1
私はM. Herlihyの定義を使用しています。並行性の高いデータオブジェクトを実装するための方法論。プログラミング言語とシステムに関するトランザクション、1993年。「ロックフリー状態は、他のプロセスによる任意の停止の失敗または遅延にもかかわらず、一部のプロセスが常に進行することを保証する」
Joe Pension

12
@ジョー:それは定義ではありません、それは含意を説明します。逆の論理的誤りに注意してください。
Ben Voigt

2
M. Herlihy、V。Luchangco、M。Moirも引用できます。障害物のない同期:例として両終端キュー。分散コンピューティング、2003年。「一部のスレッドが常に進行することのみを保証する場合、ロックフリーです」。
ジョーペンション

1
デッドロックフリーよりも具体的なスターベーションフリーもあります(他のプロセスが何を実行してもすべてのプロセスが実行されます)CaSループ(アトミックプリミティブに基づく)はそうではありません
ラチェットフリーク

5
@ジョー:他の国々がそのプロパティをデッドロックフリーと呼ぶなら、私はその用語を使うつもりです。いいえ、あなたの簡単な例はデッドロックフリーではありません。デッドロックがないことを保証するには、同期が必要なだけでなく、ロックを保持している間、どのスレッドもブロック操作を実行しないことが保証されます。「何をしたいか」は非常にあいまいで、この保証を提供するようには見えません。
Ben Voigt

11

私は、マルチプロセッサプログラミングのアート研究してきた1を、そのテキストはちょうどあなたが参照本のように、明確さに欠けています。TAMPPからの引用は次のとおりです。

引用1(ロックフリーの定義)

一部のメソッド呼び出しが有限のステップ数で無限に終了することが保証される場合、メソッドはロックフリーです。

引用2(ノンブロッキングの定義)

totalメソッドの保留中の呼び出しは、別の保留中の呼び出しが完了するのを待つ必要はありません。

引用3(ロックフリーは非ブロッキングであると主張する)

待機なしおよびロックなしのノンブロッキング進行状況条件は、システムがスレッドをスケジュールする方法とは無関係に、全体として計算が進行することを保証します。

問題は、引用3の主張が引用1の定義に明らかに従わないことです。すでに述べたように、同期キューは引用1を満たしているようです。

特に、引用3の非常にあいまいな句「システムがスレッドをスケジュールする方法とは無関係」に注意してください。これの前に「スレッドスケジューリングシステム」の正式な説明はありません。そのため、定義の意味についての先入観に基づいてプロパティを再構築する必要があります。

  1. システムは常にいくつかのスレッドの命令を実行します。
  2. 特定のスレッドの命令を実行することはありません。
  3. すべてのスレッドが検討中のメソッドを呼び出しています。

そのようなシステムでは、ブロッキングメソッドをロックフリーにすることはできません。ロックを保持しているスレッドの実行が再度スケジュールされない場合、有限数のステップでメソッド呼び出しを完了できる他のスレッドはありませんが、メソッドのステップを実行しているいくつかのスレッド。最終的に各スレッドにCPU時間を与えることを保証する、より現実的なシステムの場合、定義には非ブロッキングプロパティを明示的に含める必要があります。

ロックフリーの定義を修正

メソッドは、それが非ブロッキングである場合にロックフリーであり、さらに、いくつかのメソッド呼び出しが有限数のステップで無限に終了することを保証します。

1 Maurice Herlihy、Nir Shavit、Art of Multiprocessor Programming、Elsevier 2008、pp.58-60


1
引用1の文言は本当に奇妙です。「無限に頻繁に」とはどういう意味ですか?明らかに「常に」とは異なる何かなので、メソッドが「一部」のケースで戻らないことは問題ありませんか?
ハルク

はい、不正確な言葉がたくさんあります。とにかく「よくある」とは何ですか?「無限の実行履歴では、この特定のイベントが無限に何度も発生する」という意味だと思います。
Marko Topolnik、2016年

5

用語は常に一貫しているわけではありませんが、提案されたアルゴリズムまたはシステムについて次の質問をすることが重要だと思います。

  1. すべてのスレッドが使用できるすべてのCPU時間を許可されていても、スレッドが互いに待機してスタックする可能性があるイベントのシーケンスはありますか(そうであれば、デッドロックが発生しないわけではありません)。
  2. 1つのスレッドが任意の時間ブロックされた場合、他のスレッドが停止したり、システムの動作が任意の時間損なわれたりする可能性があります(そうであれば非ブロックではありません)。
  3. スレッドスケジューリングの少なくとも理論的に可能な組み合わせはありますか?これにより、すべてのスレッドが同じ操作を繰り返し再試行し、他のユーザーの作業を無効にして、誰も進行せずに(そうでない場合、ロックフリーではありません)
  4. 一部のスレッドに別のスレッドと比べて十分なCPU時間が与えられている場合、後者のスレッドは、その操作を無期限に再試行し続けることができます[そうである場合、待機なしではありません]。

ロックフリーアルゴリズムの重要な点の多くは、ロックフリーアルゴリズムよりも高速であるということではなく、スレッドが滞った場合に死ぬ傾向がないという事実です[このような保証が必要なのは、そのアルゴリズムは非ブロッキングですが、すべてのロックフリーアルゴリズムは]です。ロックフリーアルゴリズムでロックを使用することは可能ですが、ロック取得の試行にタイムアウトが含まれ、アルゴリズムが常に進行することを確実にするためのアルゴリズムが含まれている場合のみ(たとえば、アルゴリズムはCompareExchangeループをプライマリとして使用できます)調停方式ですが、競合が多いように思われる場合は、ロックを使用してアクセスを調停します。ロックが非常に長く保持されていると思われる場合は、他のスレッドがそのロックの使用を中止して、代わりに新しいロックを作成する可能性があります。CompareExchange、顧客がロックを放棄しても、システムの一貫性が損なわれることはありませんが、古いロックを保持していたコードは、古いロックを放棄して新しいロックに並ぶまで、何の作業も行われない可能性があります。


これは標準的な用語とは異なります。2。は非ブロッキングの標準的な意味を指し、3。はロックの自由を指します。
Marko Topolnik、2016年

一貫性のない用語の使用法を見てきましたが、「公式」の標準については知りません。最も重要なことは、アルゴリズムが提供できるさまざまな保証があることと、アプリケーション要件を満たすのに十分な保証を提供するアルゴリズムを使用することが重要です。多くの論文は上記の保証の一部のみを取り上げていますが、それぞれが要件を満たす他のどの保証よりも簡単にアプリケーション要件を満たすことができる場合があります。
スーパーキャット2016年

Art of Multiprocessor Programmingで示されている用語は「標準」であるというコンセンサスがあると思います。
Marko Topolnik 2016年

@MarkoTopolnik:それに合わせて投稿を編集します。新しいバージョンが好きですか?
スーパーキャット2016年

かっこいい
Marko Topolnik 2016年

4

あなたは文脈で引用する「定義」を見なければなりません:

共有データ構造を実装する従来の方法は、相互排他(ロック)を使用して、並行操作が互いに干渉しないようにすることです。ロックには、ソフトウェアエンジニアリング、フォールトトレランス、およびスケーラビリティに関して多くの欠点があります([8]を参照)。それに応じて、研究者は相互排除を採用しないさまざまな代替同期技術を調査しました 。同期技術は、他のスレッドの任意の遅延(または障害)が発生してもすべてのスレッドが続行し続けることが保証されている場合、待機なしです。一部のスレッドが常に進行することのみを保証する場合は、ロックフリーです。

あなたは相互排除のためにロックを使用しているので、それは彼らが話しているロックフリーの技術ではありません。


2

ロックを使用している場合でも、アルゴリズムにロックは不要ですか?

可能性はありますが、アルゴリズムによって異なります。

キューなどの単純なデータ構造があり、ロックで保護されている場合、1つのプロセスがロックを取得し、必要な処理を実行して解放できるため、1つのプロセスは常に進行できます。

それでは、ロックフリーの定義を満たしていますか?

それ自体に注意してください。

場合は、「それが何を望んでください」ステップは、他のロックを取得関与していない、そして有限の時間内に完了することが保証され、その後、あなたのアルゴリズムのこの特定の部分がデッドロック無料となります。

ただし、これらの前提条件が満たされていない場合、少なくともデッドロックの可能性があります...


マルチプロセッサプログラミングのアートのテキストを少し調べた結果、定義が正しく綴られている場合、ミューテックスはロックフリーの定義を確実に無効にするという結論に達しました。これを明確にするために、このページに回答を追加しました。
Marko Topolnik、2016年

1

あなたが与える例は以下の理由でロックフリーではありません。

1つのスレッドがロックを取得し、OSスケジューラがスレッドを無期限に一時停止した場合、一時停止したスレッドによって取得されたロックを取得できないため、すべてのスレッドが進行できなくなります。

一般的に言って、ロックを使用するアルゴリズムはロックフリーではありません。

デッドロックフリーとロックフリーは2つの異なる概念であることに注意してください。デッドロックフリーとは、デッドロックの可能性がないことを意味しますが、システム全体の進行を妨げる可能性のあるライブロックが存在する可能性があります。システム内の一部のスレッドは常に有限のステップ数で進行することを意味するため、ロックの自由はそれよりも強力です。


ウィキペディアのより慎重な定義を見てください。「アルゴリズムは、プログラムスレッドが十分に長く実行されたときに少なくとも1つのスレッドが進行するという条件を満たす場合、ロックフリーです。」これはスレッドを停止する場合を除きます。また、停止中の進行は、ロックの自由ではなく、妨害の自由によってカバーされます。
Marko Topolnik、2016年

@MarkoTopolnikコメントはまったく意味がありません。ロックの自由は閉塞の自由をカバーします。ロックフリーのものは、障害物がないものでなければなりません。そして、あなたが与えた定義は、停止しているスレッドを除外していません。
Chaoran

「理にかなっている」と「正しい」を区別するように注意してください。私の次の回答からわかるように、私のコメントは正しくありません。しかし、ウィキペディアの定義も間違っているか、少なくともあいまいです。
Marko Topolnik、2016年

@MarkoTopolnikコメントが正しくないことを認めたので、他の読者を混乱させないようにコメントを削除する必要があります。ウィキペディアは、多くの場合、不正確またはあいまいです。cs.rochester.edu/~scott/papers/2006_PPoPP_synch_queues.pdf(lock-freeの定義はセクション2.1にあります)などの学術論文で「lock-freedom」のような微妙な定義を見つける必要があります
Chaoran

はい。ロックフリーの定義の一部として非ブロッキングプロパティを含めることは、それを行う1つの方法です。それは私の回答の以前の改訂で述べられました。
Marko Topolnik、2016年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.