タグ付けされた質問 「multithreading」

テクニック、構造、および安全性の問題を含むマルチスレッド関連の質問。

7
マルチスレッドおよびマルチプロセッサプログラミングの非推奨のプラクティスはありますか?
FORTRANとBASICの初期には、本質的にすべてのプログラムはGOTOステートメントで記述されていました。結果はスパゲッティコードであり、ソリューションは構造化プログラミングでした。 同様に、ポインターはプログラムの特性を制御するのが難しい場合があります。C ++は多くのポインターで開始しましたが、参照の使用をお勧めします。STLのようなライブラリは、依存関係の一部を軽減できます。より優れた特性を持つスマートポインターを作成するイディオムもあり、C ++の一部のバージョンでは参照とマネージコードを許可しています。 継承やポリモーフィズムなどのプログラミング手法では、舞台裏で多くのポインターを使用します(ただし、構造化プログラミングでは分岐命令で満たされたコードを生成します)。Javaのような言語は、プログラマーに依存せずにポインターを削除し、ガベージコレクションを使用して動的に割り当てられたデータを管理します。 私の読書では、セマフォを使用していないように見えるマルチプロセスおよびマルチスレッドのプログラミングの例を見てきました。異なる名前で同じものを使用していますか、それとも同時使用からリソースの保護を構築する新しい方法がありますか? たとえば、マルチコアプロセッサを使用したマルチスレッドプログラミングシステムの具体例は、OpenMPです。環境に含まれていないように見えるセマフォを使用せずに、次のように重要な領域を表します。 th_id = omp_get_thread_num(); #pragma omp critical { cout << "Hello World from thread " << th_id << '\n'; } この例は、http://en.wikipedia.org/wiki/OpenMPからの抜粋です。 あるいは、関数wait()およびsignal()を使用したセマフォを使用したスレッドの相互の保護は、次のようになります。 wait(sem); th_id = get_thread_num(); cout << "Hello World from thread " << th_id << '\n'; signal(sem); この例では、物事は非常に単純であり、wait()およびsignal()呼び出しが一致していることを示すには簡単なレビューで十分であり、多くの並行性がある場合でもスレッドセーフが提供されます。しかし、他のアルゴリズムはより複雑で、複数のセマフォ(バイナリとカウントの両方)を使用し、多くのスレッドが呼び出すことができる複雑な条件を持つ複数の関数に分散しています。デッドロックを作成したり、物事をスレッドセーフにできなかったりすることの結果は、管理が難しい場合があります。 OpenMPのようなこれらのシステムはセマフォの問題を排除しますか? 彼らは問題を他のどこかに移動させますか? セマフォを使用しないようにアルゴリズムを使用してお気に入りのセマフォを変換するにはどうすればよいですか?


3
なぜグリーンスレッドではないのですか?
私はこれに関する質問がすでにカバーされていることを知っていますが(例えばhttps://stackoverflow.com/questions/5713142/green-threads-vs-non-green-threads)、満足のいく答えが得られたとは感じません。 問題は、なぜJVMがグリーンスレッドをサポートしないのかということです。 コードスタイルのJava FAQでこれを言っています: 緑のスレッドは、すべてのコードが単一のオペレーティングシステムスレッドで実行されるJava仮想マシン(JVM)の動作モードを指します。 そして、これはjava.sun.com上で: 欠点は、グリーンスレッドを使用すると、Linuxのシステムスレッドが利用されないため、CPUを追加してもJava仮想マシンがスケーラブルではないことです。 JVMには、コアの数に等しいシステムプロセスのプールがあり、その上でグリーンスレッドを実行できるように思えます。頻繁にブロックする非常に多くのスレッドがある場合、これはいくつかの大きな利点を提供します(主に現在のJVMがスレッド数を制限するため)。 考え?

6
並行性とマルチスレッドをどのように実践しますか?[閉まっている]
私は並行性、マルチスレッド、および「無料のランチが終わった」について読んでいます。しかし、私はまだ仕事でMTを使用する可能性がありませんでした。 したがって、私は、いくつかのオープンソースプロジェクトへの演習または参加を通じて、CPUヘビーMTの練習をするためにできることについての提案を探しています。 ありがとう。 編集:私は、スレッド、ミューテックス、ロックなどのツールのみを説明する本や論文ではなく、MTをCPUバウンドタスクに使用するオープンソースプロジェクト、または単にMTを使用して実装するのに興味深いアルゴリズムに興味があります。 MTを使用してレスポンシブGUIを作成する方法...

8
「何十万もの」スレッドが必要になるのはいつですか?
Erlang、Go、およびRustはすべて、安価な「スレッド」/コルーチンを使用した同時プログラミングをサポートしていると何らかの形で主張しています。ゴーよくある質問の状態: 同じアドレス空間に数十万のゴルーチンを作成するのが実用的です。 錆チュートリアルは言います: タスクは従来のスレッドよりも作成コストが大幅に低いため、Rustは標準的な32ビットシステムで数十万の同時タスクを作成できます。 Erlangのドキュメントによると: 233ワードのデフォルトの初期ヒープサイズは、数十万または数百万のプロセスを持つErlangシステムをサポートするためにかなり控えめです。 私の質問:どんな種類のアプリケーションが非常に多くの同時実行スレッドを必要としますか?最も忙しいWebサーバーだけが、数千もの同時訪問者を受け取ります。私が書いたボスワーカー/ジョブディスパッチタイプのアプリケーションは、スレッド/プロセスの数が物理コアの数よりもはるかに多い場合に、リターンを減少させます。数値アプリケーションにとっては理にかなっていると思いますが、実際には、ほとんどの人はこれらの新しい世代の言語ではなく、Fortran / C / C ++で書かれたサードパーティのライブラリに並列処理を委任します。

3
GCCはWindowsでスレッドサポートなしで死にますか?[閉まっている]
意見が必要です。GCCは常に非常に優れたコンパイラーでしたが、最近では「魅力」を失いつつあります。私は、Windows GCCにはstd::threadサポートがなく、Windowsユーザーが別のコンパイラーを使用することを強いられていることがわかりました。なぜなら、最もエキサイティングな機能がまだ欠けているからです。 しかし、WindowsでGCCがまだスレッドをサポートしていないのはなぜですか?ライセンスの問題?ABIの非互換性 (まあ、マルチスレッドを使用するクロスプラットフォームライブラリが既にいくつかあります:boost、POCO、SDL、wxwidgetsなど。GCCリリースを出荷する代わりに、既存のMIT / libpngライセンスのコードをこのホールに合うように使用するのは簡単ではないでしょうかスレッドのサポートなし?) 最近、コンパイラの比較を見ると、GCCは他のコンパイラに比べてC ++ 11の機能を最も幅広くサポートしていますが、Windowsではアトミック、ミューテックス、スレッドがまだないため、これは真実ではありません。 このトピックについてもっと知りたいのですが、私が見つけることができる唯一のことは、次の理由で助けを求める人々です: 「スレッド」はstd名前空間に存在しません GCC / TDM-GCCのチケットトラッキングとメールディスカッションを見ると、2009年からスレッドサポートのリクエストがありました。本当に何が起こっているのですか?

2
偽のウェイクアップの説明は、修正するだけの価値のないバグのように聞こえますが、そうですか?
スプリアスウェイクアップに関するウィキペディアの記事によると 「スレッドは、条件変数にシグナルを送っていなくても、待機状態から目覚めさせることができます」。 私はこの「機能」について知っていましたが、同じ記事で実際に何がそれを引き起こしたのかは知りませんでした 「スプリアスウェイクアップは奇妙に聞こえるかもしれませんが、一部のマルチプロセッサシステムでは、コンディションウェイクアップを完全に予測可能にすると、すべてのコンディション変数操作が大幅に遅くなる可能性があります。」 修正する価値のないバグのように聞こえますが、そうですか?

11
マルチスレッドのバグに悩まされる
私が管理している新しいチームでは、コードの大部分はプラットフォーム、TCPソケット、およびhttpネットワークコードです。すべてのC ++。その大部分は、チームを去った他の開発者からのものです。チームの現在の開発者は非常に賢いですが、ほとんどの場合、経験的には後輩です。 私たちの最大の問題:マルチスレッドの同時実行バグ。ほとんどのクラスライブラリは、いくつかのスレッドプールクラスを使用して非同期に作成されています。クラスライブラリのメソッドは、長時間実行されるタスクを1つのスレッドからスレッドプールにキューイングすることが多く、そのクラスのコールバックメソッドは別のスレッドで呼び出されます。その結果、誤ったスレッドの仮定に関連する多くのエッジケースバグがあります。これにより、同時実行性の問題から保護するための重要なセクションとロックを保持するだけでなく、微妙なバグが発生します。 これらの問題をさらに困難にしているのは、修正の試みがしばしば間違っていることです。チームが(またはレガシーコード自体で)試みようとしているミスには、次のようなものがあります。 よくある間違い#1-共有データをロックするだけで同時実行の問題を修正しますが、メソッドが期待される順序で呼び出されない場合に何が起こるかを忘れます。これは非常に簡単な例です: void Foo::OnHttpRequestComplete(statuscode status) { m_pBar->DoSomethingImportant(status); } void Foo::Shutdown() { m_pBar->Cleanup(); delete m_pBar; m_pBar=nullptr; } そのため、OnHttpNetworkRequestCompleteの実行中にShutdownを呼び出すことができるバグがあります。テスターはバグを見つけ、クラッシュダンプをキャプチャし、バグを開発者に割り当てます。彼は次のようにバグを修正します。 void Foo::OnHttpRequestComplete(statuscode status) { AutoLock lock(m_cs); m_pBar->DoSomethingImportant(status); } void Foo::Shutdown() { AutoLock lock(m_cs); m_pBar->Cleanup(); delete m_pBar; m_pBar=nullptr; } 上記の修正は、さらに微妙なエッジケースがあることに気付くまでは問題ありません。OnHttpRequestCompleteがコールバックされる前にシャットダウンが呼び出されるとどうなりますか?私のチームが持っている実際の例はさらに複雑であり、コードレビュープロセス中にエッジケースを見つけるのはさらに困難です。 よくある間違い#2-盲目的にロックを終了し、他のスレッドが終了するのを待ってからロックを再入力することで、デッドロックの問題を修正します。 よくある間違い#3-オブジェクトは参照カウントされますが、シャットダウンシーケンスはポインターを「解放」します。しかし、まだ実行中のスレッドがそのインスタンスを解放するのを待つことを忘れています。そのため、コンポーネントは完全にシャットダウンされ、その後、コールを予期しない状態のオブジェクトでスプリアスまたはレイトコールバックが呼び出されます。 他のエッジケースもありますが、一番下の行はこれです: マルチスレッドプログラミングは、頭のいい人でも簡単です。 これらの間違いを見つけると、より適切な修正を開発するために各開発者とエラーについて話し合うことに時間を費やします。しかし、「正しい」修正には触れなければならない膨大な量のレガシコードのため、各問題の解決方法についてしばしば混乱していると思われます。 私たちはすぐに出荷するつもりであり、私たちが適用しているパッチは今後のリリースに適用されると確信しています。その後、コードベースを改善し、必要に応じてリファクタリングする時間があります。すべてを書き直す時間はありません。そして、コードの大部分はそれほど悪くはありません。しかし、スレッドの問題を完全に回避できるように、コードをリファクタリングしたいと考えています。 私が検討しているアプローチの1つはこれです。重要なプラットフォーム機能ごとに、すべてのイベントとネットワークコールバックがマーシャリングされる専用の単一スレッドを用意します。メッセージループを使用したWindowsでのCOMアパートメントスレッドに似ています。長時間のブロッキング操作はワークプールスレッドにディスパッチされる可能性がありますが、コンポーネントのスレッドで完了コールバックが呼び出されます。コンポーネントは同じスレッドを共有することさえできます。その後、スレッド内で実行されるすべてのクラスライブラリは、単一のスレッド化された世界を想定して記述できます。 その道を進む前に、マルチスレッドの問題に対処するための他の標準的な手法や設計パターンがあるかどうかにも非常に興味があります。そして、私は強調しなければなりません-ミューテックスとセマフォの基本を説明する本を超えた何か。どう思いますか? また、リファクタリングプロセスに向けた他のアプローチにも興味があります。次のいずれかを含む: スレッド周辺のデザインパターンに関する文献または論文。ミューテックスとセマフォの紹介を超えたもの。大規模な並列処理も必要ありません。他のスレッドからの非同期イベントを正しく処理するようにオブジェクトモデルを設計する方法だけです。 さまざまなコンポーネントのスレッド化を図式化する方法。これにより、ソリューションの研究と発展が容易になります。(つまり、オブジェクトおよびクラス全体のスレッドを議論するためのUML同等物) …

3
マルチスレッドアプリケーションのUML図
シングルスレッドアプリケーションの場合、クラス図を使用して、そのアプリケーションのアーキテクチャの概要を取得します。ただし、このタイプのダイアグラムは、たとえば、異なるスレッドでクラスの異なるインスタンスが「ライブ」であるため、重いマルチスレッド/同時実行アプリケーションを理解しようとするときにはあまり役に立ちません(つまり、インスタンスへのアクセスは、それが住んでいるスレッド)。したがって、クラス間の関連付けは、必ずしもそれらのオブジェクトのメソッドを呼び出すことができるという意味ではありませんが、代わりにターゲットオブジェクトのスレッドで呼び出しを行う必要があります。 Hassan GomaaによるUMLを使用した並行、分散、およびリアルタイムアプリケーションの設計などのトピックについて掘り下げたほとんどの文献には 、スレッド境界をオブジェクト図に描画するなどの素晴らしいアイデアがありましたが、本当に便利です。 これらの図を問題ドメインの高レベルのビューとして使用するのではなく、クラス/オブジェクト、それらの相互作用、および前述のスレッド境界による制限の詳細な説明として使用します。 したがって、私は知りたい: マルチスレッドアプリケーションの理解に最も役立つとわかったのは、どのような種類の図ですか? マルチスレッドアプリケーションの特性を考慮したクラシックUMLの拡張機能はありますか。たとえば、 一部のオブジェクトは特定のスレッドに存在し、他のオブジェクトはスレッドアフィニティを持たない場合があります。 オブジェクトの一部のフィールドは、任意のスレッドから読み取ることができますが、1つのスレッドからのみ書き込むことができます。 いくつかのメソッドは同期して結果を返しますが、他のメソッドはリクエストをキューに入れて、たとえば異なるスレッドのコールバックを介して結果を返す非同期です。

7
デッドロックをデバッグするときに何を探しますか?
最近、スレッドを多用するプロジェクトに取り組んでいます。私はそれらを設計してもいいと思います。ステートレス設計を可能な限り使用する、複数のスレッドが必要とするすべてのリソースへのアクセスをロックする、など。関数型プログラミングの私の経験は非常に役立ちました。 しかし、他の人のスレッドコードを読むと、混乱します。私は今、デッドロックをデバッグしています。コーディングスタイルとデザインは私の個人的なスタイルとは異なるため、潜在的なデッドロック状態を見つけるのは困難です。 デッドロックをデバッグするときに何を探しますか?

4
ロックの競合状態を防ぐものは何ですか?
データ競合とは何か、そしてロック/ミューテックス/セマフォがそれらを防ぐのにどのように役立つのかを理解しています。しかし、ロック自体に「競合状態」がある場合はどうなりますか?たとえば、おそらく同じアプリケーション内にあるが、異なるプロセッサで実行されている2つの異なるスレッドが、まったく同時にロックを取得しようとします。 それではどうなりますか?それを防ぐために何が行われますか?それは不可能ですか、それともまったくありそうもないことですか?それとも、実際に発生するのを待っている競合状態ですか?

10
ステートマシンとスレッド
アラン・コックスはかつて「コンピューターは状態機械です。スレッドは状態機械をプログラムできない人々のためのものです」と言っていました。 Alanに直接質問することは謙虚な選択肢ではないので、ここで質問します。1つのスレッドとステートマシンのみを使用して、Javaなどの高レベル言語でマルチスレッド機能をどのように実現しますか?たとえば、実行する2つのアクティビティ(計算とI / Oの実行)があり、1つのアクティビティがブロックできる場合はどうなりますか? 高レベル言語のマルチスレッド化に代わる「ステートマシンのみ」の方法を使用できるか?

6
マルチスレッド:間違っていますか?
私は音楽を再生するアプリケーションに取り組んでいます。 再生中は、同時に発生する必要があるため、多くの場合、別々のスレッドで発生する必要があります。例えば、一緒に聞くことにする和音必要のノートは、それぞれがで再生する独自のスレッドが割り当てられているので(編集明確にする:。呼び出しはnote.play()、ノートの再生が完了するまでスレッドをフリーズする、と私は3を必要とする理由です別々のスレッドで同時に3つのノートを聞くことができます。) このような動作は、音楽の再生中に多くのスレッドを作成します。 たとえば、短いメロディーと短いコード進行を伴う音楽を考えてみましょう。メロディ全体を1つのスレッドで再生できますが、進行には3つのスレッドが必要です。各コードには3つの音符が含まれているためです。 したがって、進行を再生するための擬似コードは次のようになります。 void playProgression(Progression prog){ for(Chord chord : prog) for(Note note : chord) runOnNewThread( func(){ note.play(); } ); } したがって、プログレッションには4つのコードがあり、3 notes * 4 chords * 2 times24スレッドを開くよりも2回コードを再生すると仮定します。そして、これは一度だけ再生するためのものです。 実際には、実際にはうまく機能します。顕著な遅延や、これに起因するバグに気付きません。 しかし、私はこれが正しい慣行なのか、それとも根本的に間違っているのかを尋ねたかったのです。ユーザーがボタンを押すたびに非常に多くのスレッドを作成するのは妥当ですか?そうでない場合、どうすれば異なる方法で行うことができますか?

3
パフォーマンスを向上させるためにマルチスレッドがしばしば好まれているのはなぜですか?
この質問は、Software Engineering Stack Exchangeで回答できるため、Stack Overflowから移行されました。 6年前に移行され ました。 私は質問があります、それはプログラマーが一般的に並行性とマルチスレッドプログラムを好むように思われる理由についてです。 ここで2つの主なアプローチを検討しています。 基本的に信号に基づく非同期アプローチ、または新しいC#5.0などの多くの論文や言語で呼ばれる非同期アプローチ、およびパイプラインのポリシーを管理する「コンパニオンスレッド」 並行アプローチまたはマルチスレッドアプローチ 私はここでハードウェアと最悪のシナリオについて考えていると言いますが、この2つのパラダイムを自分でテストしました。物事をスピードアップしたり、リソースを有効に活用したい場合は、マルチスレッドについて話します。 CPU内にメモリコントローラーを提供しないIntelクアッドコアを備えた古いマシンでマルチスレッドプログラムと非同期プログラムをテストしました。メモリはマザーボードによって完全に管理されています。マルチスレッドアプリケーションでは、3-4-5のような比較的少数のスレッドでさえ問題になる可能性があり、アプリケーションは応答せず、遅くて不快です。 一方、優れた非同期アプローチはおそらく高速ではないかもしれませんが、最悪ではありません。私のアプリケーションは結果を待つだけでハングせず、応答性があり、はるかに優れたスケーリングが行われています。 また、スレッドの世界でのコンテキストの変更は、実際のシナリオではそれほど安くないことを発見しました。実際には、計算するために相互に循環してスワップする必要のあるスレッドが2つ以上ある場合、実際には非常に高価です。 現代のCPUでは、状況はそれほど違いはありませんが、統合されたメモリコントローラですが、私のポイントは、x86 CPUは基本的にシリアルマシンであり、メモリコントローラはマザーボード上の外部メモリコントローラを備えた古いマシンと同じように動作することです。コンテキストスイッチは依然としてアプリケーションに関連するコストであり、メモリコントローラーが統合されているか、新しいCPUに2コア以上あるという事実は私にとってはお買い得ではありません。 私が経験したコンカレントアプローチは理論的には良いが、実際にはそれほど良くありません。ハードウェアによってメモリモデルが課されているため、このパラダイムをうまく利用することは難しく、使用からデータ構造を複数のスレッドの結合に使用します。 また、両方のパラダイムは、特定の時点でタスクまたはジョブが実行されるときにセキュリティを提供しません。機能的な観点からは、それらは本当に似ています。 X86メモリモデルによると、なぜ大多数の人々は、非同期アプローチではなく、C ++で同時実行性を使用することを提案するのでしょうか。また、コンピュータの最悪のシナリオを考えてみてください。コンテキストスイッチは、おそらく計算自体よりも高価です。

9
マルチスレッド同期のインタビューの質問:m個のスレッドからn個の単語を見つける
この問題は、単一のスレッドではなく、複数のスレッドを使用したソリューションの恩恵を受けることができますか? インタビューで、複数のスレッドを使用して問題を解決するように依頼されました。私には、複数のスレッドは何の利益ももたらさないように見えます。 問題は次のとおりです。 n個の単語を含む段落が与えられ、m個のスレッドが与えられます。あなたがする必要があるのは、各スレッドが1つの単語を印刷し、次のスレッドに制御を与える必要があることです。このように、各スレッドは1つの単語を印刷し続け、最後のスレッドが来た場合、最初のスレッドを呼び出す必要があります。すべての単語が段落に印刷されるまで、印刷が繰り返されます。最後に、すべてのスレッドが正常に終了する必要があります。どのような同期を使用しますか? ここではスレッドを活用できないと強く感じていますが、インタビュアーは私の同期スキルを測定しようとしていると考えています。この問題で、複数のスレッドに価値をもたらす何かが欠けていますか? コードは不要です。考えてみてください。自分で実装します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.