0

これは奇妙な質問なので、長い説明を提供しようとします。
シングルコアマシンで実行しているとしましょう。そして、2 つのスレッドがあります。ミューテックスに関する従来のプロデューサー コンシューマーの問題を考えてみましょう。シングル コア マシンで実行する場合 (1 コア HT なし) を疑問に思っています:
C++ でこれら 2 つのスレッドの実行を 1 つに融合して、mutex を単純な int ストア/ロード操作として実装できるようにする方法はありますか?ミューテックスの代わりに。たとえば、次のように動作します。現在の buffer_idx がprocessed_idx よりも大きい場合、統合スレッドのプロデューサー コードは循環バッファーにデータを入れるだけで、コンシューマー コードはバッファーから読み取るだけです。

これはばかげた質問のように思えますが、多くの組み込みのものはまだ 1 コアです。簡単にするために、両方のスレッドがフォームであると仮定します

while(! shutdown)
{
//...
}

両方の while 体を大きな while に入れるだけで、期待どおりに機能しますか?

4

4 に答える 4

1

プロデューサーとコンシューマーの両方を1つのスレッドに入れることができます。しかし、何のために?それらのストア/ロード操作は順次実行されます。それらの間には常に「平和」があります(予期しない状況を除く)。すべてのプロデューサーストア操作に対して、コンシューマーロード操作があります(条件ステートメントがない場合、yesの場合、プロデューサーは停止し、コンシューマーコードがすべてのものをロードするまで待機してから、ループが再開します)。IMO、このようなモデルを使用すると、コード内の実際の状況のごく一部しか記述できません。

編集:シングルコアマシンを使用している場合でも、ロジックを複数のスレッドに分割すると、すべてのものを1つのスレッドで作成するよりもパフォーマンスが向上します。たとえば、プロデューサーがいくつかのものを作成している間、あなたのコンシューマーは、いくつかのものが保存されていても何もしません。それは時間の無駄です。消費者が何かをロードした後、彼はあなたのロジックの別の要素に何かを与えなければならないと想像してください。他の要素がたくさんある場合、消費者の後に立って、それらはすべて1つのロジック要素(プロデューサー)だけを待ってから、消費者など。ほとんどの場合、プロセッサがスレッドを切り替えるのにかかる時間は、ものを生成または消費するのに必要な時間よりも短くなります。

于 2012-07-31T07:19:33.747 に答える
0

次々と無限ループがあるということは、決して実行されないことを意味するので、毎回適切な場所にジャンプする「魔法の」GOTO ステートメントがあると仮定しましょう。それから、はい、GOTO は本質的にここではモニターなので、2 つの while ループを一緒にするとうまくいくかもしれませんが、それはあなたが望むものではないかもしれません。

一方、ループが適切なタイミングで終了するとします。2 つのスレッドを (CPU 時間をスライスせずに) 1 つに融合すると、最初の問題は本質的に無効になります。実行中のプロセス自体の代わりに除外するものは何もないため、ミューテックスは必要ありません。

また、考慮すべきことは、シングルコア システムにも同時実行性の問題があり、タイム スライスで複数のスレッドを実行して、マルチコア システムの動作を (ある意味で) シミュレートすることです。同じ多重化のものは直接転送可能でなければなりません。

于 2012-07-31T07:25:52.820 に答える
0

あなたはまだ同じように注意する必要があります。両方のスレッドを同時に実行することはできませんが、予防的なマルチタスクを使用すると、コードが中断され、他のスレッドが任意の時点で実行される可能性があるため、一般的にはロックする必要があります。

一般的なことの 1 つは、最初のスレッドで「キューに格納」操作を行う代わりに、他のスレッドで「キューからのプロセス」関数を直接呼び出すことです (スレッドは 1 つだけです)。適切な設計を行えば、シングル コアでシングル スレッドを実行し、複数のコアがある場合はマルチスレッドで実行するコードを作成できます。これにより、コアが 1 つしかない場合にロックする必要がなくなります。

于 2012-07-31T07:26:00.277 に答える
0

このような「保護されていない」キューは、組み込みのもので一般的です。スレッドと割り込みドライバーの間で通信します。そのようなドライバーは、mutex をまったく使用できません (ただし、通常、完了したプロトコル パケットが保護されていないキューにプッシュされた場合などに、スレッドを準備するためにセマフォを通知できます)。ドライバー通信には、一方の端がもう一方の端がそれを中断できないことを完全に確信しているという利点があります-ドライバーはスレッドによって中断されません。これにより、インデックス/ポインターが「安全な」順序で更新されるようにすることがかなり簡単になります。

ただし、2 つのスレッド間では、事態はさらに困難になります。インデックス/ポインターが操作されている間、いずれかの端が他の端によっていつでも中断される可能性があります。私は常にそのようなキューをミューテックスでロックします (埋め込み通信に使用するスレッド間キューには内部ストレージがありません。メッセージ自体には内部転送リンクがあり、ロックフリーのキューはさらに厄介です)。

于 2012-07-31T08:41:33.627 に答える