- ベストアンサー
C++でシングルスレッドで同期処理すべきか?
こんばんは。 C++でプログラミングの勉強をしている者ですがシングル スレッドで同期処理をし、メイン処理からそのスレッドを実行した場合は スレッドの処理が終わるまで、そのスレッドに扱われる変数にアクセスできないという 認識で会っていますか? そもそも同期処理というのが、マルチスレッドで、同じメソッドを扱う場合、片方の処理が 終わるまでもう片方の処理は待機しているという認識で合ってますか? メイン処理からスレッドを作成し、スレッドの動きを止め、あるタイミングでスレッドの 処理を再開させる処理をメイン処理で実装することはできるでしょうか?
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
>シングルスレッドで同期処理 スレッドの意味を理解していますか? スレッドが一つしかないのに、何と「同期」するんですか? >スレッドに扱われる変数にアクセスできない そんなことはありませんよ。 終了しなくても同期が必要なことはあるし、それに使う イベントやセマフォハンドルは双方で操作します。 その他、特定のフラグやログファイルハンドルなども 双方で使う可能性が高いです。 >同期処理というのが、マルチスレッドで、同じメソッドを扱う 何かの勘違いですかね? 「同じメソッド」ではなく、どこかの一点で、状態を合わせる というのが同期です。 例えば、ファイルのコピーを考えましょう。 入力と出力を別々のスレッドで処理する場合、出力側は 入力が完了するまで、実行できませんよね。 だから、入力側が完了したことを通知するまで、待機 します。入力側は入力が完了したら、出力側にそのことを 通知し、今度は出力が完了するまで待機します。 入力側はReadだし、出力側はWriteだから同じメソッドでは ありません。 今の例をプログラムしたらどうですか? バッファを二つ(便宜的にAとB)用意し、Aに入力したら 出力側に通知して、引き続きBに入力します。出力側は 通知があったらAを出力します。次に通知があったら、 今度はBを出力します。つまり、「Bへ入力」「Aから出力」が 同時に実行されることになります。 この時、双方のスレッドではバッファ、ファイル、入力バイト数、 同期用のイベントなど、同じ変数を参照/操作することになる はずです。 このような方法でコピーすると、理論上はシリアルに実行する 場合の半分の時間で転送が可能です。 同一デバイスのファイルの転送では効果が少ないのですが、 通信を利用して異なるPC間の転送などを行う場合は非常に 有効です。経験的に実行時間は1/2以下になります。 つまり、理論値よりも高速です。 尚、ついでに両方のスレッドで同じファイルにログを出力する ようにすると、何も制御しない時は出力が重なって内容が 崩れます。これを防ぐためミューテックスを使うことになる でしょう。これで、同期制御と排他制御の両方が学べます。
その他の回答 (2)
> メイン処理からそのスレッドを実行した場合 メイン処理ですでにスレッドが一つ。メイン処理から新しくスレッドを作って実行すると、合計でスレッド二つ。その時点でもうシングルスレッドではないです。 > そのスレッドに扱われる変数にアクセスできない その変数がスコープ内にあり、排他制御されていんければ、どのスレッドからもアクセスできるでしょう。 > 同じメソッドを扱う場合、片方の処理が終わるまでもう > 片方の処理は待機しているという認識で合ってますか? それはモニタのことですね。同期処理には違いありませんが、全ての同期がモニタではありません。セマフォやランデブなど同期には様々な形態があります。 > スレッドの動きを止め、あるタイミングでスレッドの > 処理を再開させる処理をメイン処理で実装することは 察するにランデブ(複数のスレッド同士の待ち合わせ)を実現したいのではないでしょうか。 既存の実装(例えば C++CSP2 [http://www.cs.kent.ac.uk/projects/ofa/c++csp/] のチャネル)を使うか、あるいは専門の文献で調べれば同等の処理をセマフォやモニタを駆使して自力で実装することもできます。
お礼
ランデブなんて言葉は初めて聞きました。 そんなスレッド処理があるんですね。 そういったものを調べて対処しようと思います。
- wormhole
- ベストアンサー率28% (1626/5665)
同期処理と排他制御を混同されていませんか?
お礼
なるほど確かにそうですね。 自分が説明しているものは排他制御ですね。 同期処理ではありませんでした。 非同期処理とは違うんですね。
補足
後で調べてみます。
お礼
ミューテックスは、二重起動防止に役立ちました。 それを学んでおいたほうがよさそうですね。 IO処理で同期処理をし、ミューテックスでログが被るのを 防ぐんですね。 勉強します。
補足
同期制御と排他制御の勉強が足りていないと思いました。 そこらへんはしっかり学んでおくべきですね。