0

次のようなコードがある場合(構文は無視してください。言語を指定せずに理解したい):

count = 0

def countDown():
  count += 1

if __name__ == '__main__':
    thread1(countDown)
    thread2(countDown)
    thread3(countDown)

ここでは、コアが 1 つしかないCPU を使用しています。他のスレッドによって上書きされる可能性がある場合に備えて、変数カウントへのロックが本当に必要ですか。

わかりませんが、言語が気になる場合は、Java、C、Pythonで説明してください。どうもありがとうございました。


ありがとう、ロックが必要だということがわかりました。しかし、ここで別の質問があります。いつマルチスレッドを使用する必要がありますか?

CPU は 1 つのインストラクタのみを実行するため、マルチスレッドはスレッドの切り替えを管理するのにより多くの時間がかかり、計算時間を節約できないようです。

4

6 に答える 6

2

技術的には、一般的にはそうです。たぶん、この特定の例ではありません。しかし、アトミック関数がいくつかの命令で構成されていると想像してください。オペレーティングシステムは、一度に多くのスレッドを実行できます。1つのステップをいくつか実行してから、OSに戻り、続行するプロセス/スレッドを選択します。すべてのスレッドを開始し、それらを切り替えることができます。1つのCPUでも。次に、すべてのスレッドが同じメモリアドレスで動作し、変数を共有します。

編集:2番目の質問に答えます。コアが1つある場合、マルチスレッドが必要になるケースは1つだけです。これは、スレッドの1つがロックされる可能性があり、このときにそれを監視するか、他のことを行う必要がある場合です。1つの実用的な例はサーバーです。同時に複数のクライアントにサービスを提供したい場合は、それらを切り替える必要があります。それらをキューで提供した場合、1つの不良クライアントがプロセス全体をハングさせる可能性があります。

計算を行う場合は、これを使用してI/Oと計算を分割できます。しかし、それが有用または必要とされるには、非常に極端なケースである必要があります。

于 2012-09-22T03:35:02.087 に答える
1

ロックを使用する代わりに、カウンターをインクリメントするような単純なものの場合、cには、スレッドセーフな方法で操作を実行するアトミック関数を見つけることができます。GCCは、これらのアトミック組み込み関数を定義します。これらは通常、すべての特定の環境でパブリック関数呼び出しにラップされます http://gcc.gnu.org/onlinedocs/gcc-4.5.0/gcc/Atomic-Builtins.html

Mac OS Xは、これらを定義します。たとえば、https://developer.apple.com/library/mac/#documentation/cocoa/Conceptual/Multithreading/ThreadSafety/ThreadSafety.html

これらは、ロックよりも機能が制限されているため、ロックよりも効率的である可能性があります。

于 2012-09-22T04:08:38.610 に答える
1

はい、おそらくまだロックが必要です。コードcountDownはおそらく次のようにコンパイルされます。

load global variable "count" into register x
x = x + 1
save register x into global variable "count"

そこの真ん中に糸の切り替えがあると困ります。実際には、悪い動作を得るために 2 番目のコアは必要ありません。

countDownアトミック命令にコンパイルされる場合があります。たとえば、 にはそのような命令がありますがx86、コンパイラがそれらを使用することを保証する方法はありません (アセンブリを自分で作成する場合を除いて)。

于 2012-09-22T03:57:22.390 に答える
0

ロックの問題は、他のポスターによってすでに十分に説明されています。

もう1つの質問もかなり簡単です。ほとんどのアプリはマルチスレッド化されており、ブロックできる複数のI/OストリームでI/Oパフォーマンスを向上させます。今、1つで入力しています。ブラウザは、マウスとキーボードでのネットワークアクティビティとユーザー入力に応答する必要があります。多くの場合、「同時に」両方を実行する必要があります。ユーザー入力とネットワーク通信は、それぞれ非常に低速で低速です。どちらもブロックされます。したがって、GUIとネットワーク通信は異なるスレッドで実行されます。これは、CPUコアが1つしかない場合でも発生する必要があり、そうしないと、GUIが応答しないことが多い古い「Windows3.1」スタイルの「砂時計アプリ」になります。複数のスレッドを必要とするこの問題は、非同期I / Oにも当てはまることに注意してください。これは1つのスレッドで実行されているように見えますが、カーネルスレッド/プールでサポートされています。ほとんどのブロッキングはカーネルに移動されます。

シングルコアボックスについては以上です。複数のスレッドを使用してCPUを集中的に使用する計算を高速化することはできませんが(実際、気付くと、スレッドの速度は低下します)、高性能のI/Oに使用できます。多くのアプリは、私たち全員がシングルコアのPentiumとWindows 95を使用していたときにマルチスレッド化されました。これは、計算を高速化するのではなく、I/Oを最適化するためです。

于 2012-09-22T09:04:33.763 に答える
0

最も単純な例として、1 つの変数を共有し、1 つのアトミック命令を実行する複数のスレッドを作成します。スレッドがどこで中断されても、その状態は共有リソースの命令の完全な前または完全な後のいずれかです。

この場合、x86 インクリメントはアトミックであるため、スレッド セーフです。一貫性や冪等性を維持するためにロックは必要ありません。

于 2012-09-22T03:43:46.847 に答える
0

マルチスレッドが必要になるのはいつですか?

私には、2 つの異なるアプリケーションがあります。

  • 複数のスレッド (理想的にはコアごとに 1 つ) が問題全体のごく一部を長時間にわたって処理する場合の並列処理。必要なコードとデータは小さく、理想的にはコアの L1 および L2 キャッシュに収まります。ここでのボトルネック (パフォーマンスが重要な場合) は、メモリ帯域幅と、それをできるだけ少なく使用する方法です。
  • もう 1 つは、プログラムの異なるコンポーネントが多かれ少なかれ互いに独立して動作し、処理要件が時間の経過とともに変化する場合です。1 つの例として、少なくとも 3 つの独立したコンポーネントを持つメール (SMTP) サーバーがあります。SMTP クライアントからメールを受信する SMTP サーバー、他の SMTP サーバーにメールを送信する SMTP クライアント、実際のアドレスを検索するネーム クライアントです。 SMTP クライアントがメールを送信する必要があります。
于 2012-09-22T06:51:35.347 に答える