4

もう1つのおそらく非常識なスタイルの質問:

並行性をどのようにロックする必要がありますか?エグゼキュータまたは呼び出し元は、スレッドをロックする責任がありますか?

たとえば、特定の言語ではありません。

Caller::callAnotherThread() {
    _executor.method();
}

Executor::method() {
    _lock();
    doSomething();
    _unlock();
}

また

Caller::callAnotherThread() {
    _executor.lock()
    _executor.method();
    _executor.unlock()
}

Executor::method() {
    doSomething();
}

スレッド化とロックについてはほとんど知らないので、コードが堅牢であることを確認したいと思います。2番目のメソッドは、スレッドセーフでない呼び出しを許可します...技術的には、いかなる種類のロックも実行せずに_executor.method()を呼び出すことができます。

ヘルプ?

ありがとう、

4

3 に答える 3

5

発信者ではなく、発信者がロックを行う必要があります。同期する必要があるものを知っているのは呼び出し先だけであり、同期する必要があることを確認できるのは呼び出し先だけです。発信者にロックをかけたままにすると、次の3つの悪いことが起こります。

  1. 関数/クラスのユーザーの負担が増え、設計の粘度が上がります。
  2. 呼び出し元がロックを取得せずに共有状態を更新できるようにします。
  3. 異なる関数が異なる順序で複数のロックを取得する場合、デッドロックの可能性を導入します。
于 2010-09-10T19:42:53.563 に答える
1

内部でロックを使用する場合は、マニュアルのドキュメントに注意する必要があります。または、コードが並列実行のボトルネックになり、ユーザーが真実を知るのが難しくなります。

于 2011-06-29T07:48:44.507 に答える
1

相互に関連する複数の詳細な操作を一度に実行する必要がある場合、または内部構造を参照して作業する必要がある場合、外部ロックには利点があることを学びました。他のスレッドから安全にするために一連の作業が必要な限り、ロックを保持できます。 。

例:アイテムのリストを管理するコンテナーは、1つのアイテムへの変更可能な参照を取得するためのAPIを提供したい場合があります。外部ロックがないと、関数呼び出しが終了するとすぐに、別のスレッドがデータをロックして変更する可能性があります。もっともらしい解決策は、1つのアイテムのコピーを返すことですが、これは非効率的です。

そうは言っても、場合によっては、1回の関数呼び出しより長くロックを保持したくないと確信できる場合は、内部ロックのAPIがよりクリーンになる可能性があります。

于 2019-08-06T16:08:56.220 に答える