• ベストアンサー

クリティカルセクションの用途について

クリティカルセクションの用途について 現在VC++2008でEnterCriticalSectionを使用して複数の変数を管理していますが、 アプリケーションの初期化のとき(シングルスレッドのとき)に一度だけ書き込み、その後複数のスレッドから読み込む変数の場合、読み込み時にクリティカルセクションにする必要があるでしょうか?

質問者が選んだベストアンサー

  • ベストアンサー
  • nda23
  • ベストアンサー率54% (777/1415)
回答No.1

参照しかしないのならマルチスレッドでも大丈夫なのですが、 初期化があるので、データとしては読み書き可となっていると 思います。コンパイラはそういう事情は酌量できないので、 警告メッセージが出たりします。 ルールとして変更しないというのであれば、警告は無視して よいでしょう。参照時にクリティカルセクションにする必要は ありません。

msms001999
質問者

お礼

ありがとうございます。 クリティカルセクションの使用条件をいくつか見つけたので迷ってましたが、参考になります。

全文を見る
すると、全ての回答が全文表示されます。

その他の回答 (1)

  • chie65535
  • ベストアンサー率44% (8573/19479)
回答No.2

>読み込み時にクリティカルセクションにする必要があるでしょうか? ありません。 クリティカルセクションとは「複数のスレッドが同時に1つのリソースを利用する場合に破綻しないようにするもの」です。 「読み込むだけ」であれば「破綻させようにも破綻させられない」ので、クリティカルセクションである必要はありません。 クリティカルセクションにしないとならないのは「変数の値を変化させる時」だけです。 「変数の値を変化させる時」には、実際には ・変数を読み込む ・値を加減算する ・変数に書き込む という3つの処理をします。 この3つの処理は連続して実行されねばならず、読み込みから書き込みまでの間に他のスレッドに切り替わって「同じ変数を増減」させると、変数の値が正しく増減されません。 ○失敗する例 初期の変数の値は3。スレッド1が値を1加算、スレッド2が値を1減算するのが同時に発生。 ・スレッド1が変数を読み込む(値は3) ・スレッド1が値を1加算する(3を4にする) ・スレッド2が変数を読み込む(値は3) ・スレッド2が値を1減算する(3を2にする) ・スレッド2が変数に書き込む(2を書き込む) ・スレッド1が変数に書き込む(4を書き込む) 「1加算」と「1減算」を行うのですから、両方のスレッドが実行し終わった時点では、変数は3に戻っていなくてはなりません。 しかし、加減算処理をクリティカルセクションにしていない為、両方のスレッドが実行し終わると、変数は4になってしまっています。 なので、このような「変数の値を増減させる時」には、クリティカルセクションにする必要があります。

msms001999
質問者

お礼

ありがとうございます。 書き込む必要があるときはクリティカルセクションするようにしています。 書き込みが読み込みにまったく関与していない状況で、とあるスレッドが書き込み、とあるスレッドが読み込む場合とかもクリティカルセクションが必要になる場合があったり、 回りに回って結局読み込みが書き込みに変化を与えていたということもあったので。

msms001999
質問者

補足

修正します >>回りに回って結局読み込みが書き込みに変化を与え 回りに回って結局書き込み内容が読み込み内容に変化を与え

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • クリティカルセクションの使用箇所について

    スレッドAで通常読み書きを行っている、非常に関係性の深い変数が複数あり、それらは書き換えられる場合、同一関数内などでほぼ同時に書き換えられるとき スレッドBからは全く書き換えは行わず、読み取り専用のアクセスのみをするとし 一つのCRITICAL_SECTIONでそれらを全て保護するとすれば Aで書き換えを行う(或いはそのための計算)部分は全てを囲み (つまり全ての変数を囲う) また、それらの変数がスレッドBから参照される部分は囲む これでスレッドセーフになり、それ以外は囲う必要はない。 (例えばスレッドAから単に読み取り専用のアクセスをされる場合などは普通にシングルスレッドと同様の考え方で良い) という考えで問題ないでしょうか? また、スレッドAからしか書き換えを行わなければ いくつ読み取り専用の別スレッドが出来たとしても 同様に Aで書き換えを行う部分と スレッドCやスレッドD・・・ から参照される部分さえ囲んでおけばスレッドセーフになる という考えで問題ないでしょうか?

  • 「スレッド」の概念について質問

    スレッドとは、「1つのプログラムにおいての1つの処理(メソッド)」のことで、これはシングルスレッドともよぶ。 マルチスレッドは、複数の処理を「同時に実行する」こと。但し、実際にはcpuは1つなので、擬似的に複数処理をしているようにみせかけている。 例えば、マルチスレッドは、ブラウザに例えれば、画像をダウンロードしながら、画面をスクロールしたりというように、複数の処理を同時に実行している。そして、この処理の1つ1つがスレッド。 こういうことでしょうか?

    • ベストアンサー
    • Java
  • この用途に適したPCは?

    数年前に買った恐らく一番初期のVAIO-Wを使っているのですが、調子が良くないまま初期化をしたりいろいろとやって騙し騙し使っていましたが、最近になってさすがに次のPCを考えてもいいかなぁと思っています。 そこで、私の用途に適しているPCを教えていただければと思います。 基本的にはメーカーの完成PCで考えているので、そちらのアドバイスの方が嬉しいのですが、自作の方がいいというアドバイスがあれば考えます。 予算は特に決めていませんが、30万を超えるとなると厳しいです。 参考までに、PCの知識はハードウェアに関してはかなり疎いですが、ソフトウェアに関しては中級レベルにあると思います。 用途 ・ネット閲覧がメインです。 ・Adobeフォトショップ・イラストレーターなどのソフトを本格的によく使います。 ・画像管理や動画管理・編集などもそこそこの頻度でやります。 ・TVは今のPCについているのですが、ボードが壊れたらしく見れません。できればTVも見たいです。 「このメーカーはこういう用途に強い」や、「その用途ならこのくらいのスペックは欲しい」など、メーカーの特徴や必要スペックを教えていただけると嬉しいです。 よろしくお願いします。

  • マルチスレッドについて。

    今、大きな配列を元に処理を行うプログラムを作成しています。 シングルスレッドでも十分速度を向上するようチューニングに成功しましたが、マルチスレッド化をすればさらに速度を向上させることができるだろうと考え、先日マルチスレッドかに成功しました。 しかし・・・奇妙な現象が起こりました。 マルチスレッドで性能を引き出すには、排他制御はないほうが良いと考え、メモリは食いますがスレッドに与える入力情報(大きな配列)を2つ用意し、排他制御なしの2スレッドを実行できるようにしました。しかしやはりメモリを消費しすぎてしまうため、配列にアクセスする部分のみ排他制御を行うようクリティカルセクションを設定し入力情報を2スレッドで共有して処理を行うよう組み替えました。 結果、やはり排他制御なしの場合よりはるかにスピードダウンしてしまい、シングルスレッドより少し早い処理時間で終了してしまいました。 余りにも悔しいため、ちょっと危険な実験だとは思いましたが、入力情報を2つのスレッドで共有しているにもかかわらず、排他制御の部分、つまりクリティカルセクションを取り除いて実行してみようと考えました。予想としては同時にアクセスし衝突が起きてエラーで停止してしまうと考えましたが・・・・・・ 結果なぜかエラーなく処理をし続け、普通に終了してしまいました。 これはなぜでしょう? 偶然にも共有情報に同時にアクセスすることがなかったためでしょうか?

  • マルチスレッドの実行順序の制御

    お世話になります。 現在作っているプログラムで別スレッドを走らせて処理をしているのですが、問題に突き当たりお知恵を借りたく質問しました。 グローバル変数があり、イベントが発生するとイベントハンドラ内で別スレッドを作成し、そのグローバル変数にイベント発生時間を追記していきたいのです。下のようにクリティカルセッションを用いて多重書き込みは禁止しています。 string g_Value; EventProc(){ createThread(,,,Thread_Proc.....); } Thread_Proc(){ EnterCriticalSection(&m_cs); g_Value += Now(); LeaveCriticalSection(&m_cs); } しかし、1つのスレッドが終了しないうちに2,3個追加でスレッドが立ち上げられた場合、それらは発生順に実行されないようです。 なにか順番を管理するいい方法はないでしょうか?

  • マルチスレッドの疑問点と配列について

    こんばんわ。 VC++.NET2003を用いて、C言語プログラミングを行っています。以下に質問内容をまとめます。 1.現在、マルチスレッドを行っています。マルチスレッドの注意点として、 ・スレッドが複数同時に処理(現在2スレッド)され、それぞれのスレッドで同一のグローバル変数をアクセスする。 ・各スレッドで使用しているスタティック変数はプロセスとして1つの領域に確保される。 と記述されていました。 現在、2スレッド動かしているのですが、2スレッド共通で使用したい変数がある場合は、グローバル変数として宣言してよいのでしょうか? スタティック変数というのは、 static int i を指すのでしょうか・・・・初心者的発言で申し訳ありません。 次にもう一つ質問させていただきます。 配列を整数型で10000要素、静的に用意します。 これを、memset関数ですべての番地に0を初期値として入れておきます。 たとえば、9000という数字があった場合、9000番に整数値9000を格納する。また、56では56番に56を格納する。 そして、最終的に10000要素を走査し0の場所をカウントする。 ということは可能でしょうか?もしよろしければ、サンプルを教えていただきたいと思っています。 よろしくお願い致します。

  • 「UIスレッド」「マルチスレッド」の違い

    Androidで、「UIスレッド」「マルチスレッド」の違い、を教えてください。 ■下記理解で合ってるでしょうか? Androidは、「シングルスレッド」の「UIスレッド」モデルなので、それを「マルチスレッド」で動かそうとすると、「ワーカースレッド」で処理する必要がある ・「マルチスレッド」=「マルチタスク」? ・「UIスレッド」とは、メインスレッドが「GUI (グラフィカルユーザーインターフェイス) 処理」を行うものを指す? ・つまり、「Android」=「UIスレッド」? ・「UIスレッド」って何の用語? Androidに特化した用語? それともJAVAの用語? あるいはそれ以外?

    • ベストアンサー
    • Java
  • 割り込み処理のシミュレート

    現在開発している組み込み系システムのシミュレートをVCで行いたいと考えています。 組み込み系のシステムは簡単に言うと、 普段はメインループでくるくる回っており、1ms毎にタイマ割り込みが発生し、変数の値を書き換え、メインループではその変数の変化によって何か処理を実行するというものです。 このようなシステムをVCでできるだけ同じようにシミュレートするため、マルチスレッドを用いようと考えているのですが、以下の性質を実現することは可能でしょうか? ・メインスレッド実行中はタイマ割り込みスレッドは割り込み可能。 ・タイマ割り込みスレッド実行中はメインスレッドは割り込んでこない。 ・メインスレッドで特定の区間タイマ割り込みスレッドの割り込みを禁止できる。 ・高速シミュレートを行いたいため、割り込みの禁止などはできるだけ低負荷で行いたい。(ミリ秒単位だとNG) ・複数の割り込みスレッドがある場合、各スレッドごとに割り込みレベルを設け、このレベル以下を割り込み禁止など行いたい。 スレッド以外の実現方法などあればそちらもご教授願いたいです。 よろしくお願いします。

  • クラスでスレッド作成

    VC++2008Express WIN32APIでRS232Cの通信用クラスを作成しています。 RS232Cの受信用スレッドを作成して 1ポートの受信処理をするようにはできます。 ですが ポート追加するたびにクラスをインスタンス化して受信用スレッドを 作成したいのですが、スレッド作成するには使用する変数などを staticにしないといけないため、クラスを複数インスタンス化できません。 どのような手法でクラスから複数スレッドを作成することができるのでしょうか? 分かりにくい説明ですが、参考になるものなどありましたら、 よろしくお願いします。

  • staticのメモリ共有について

    staticについて調べたのですが、その内容があっているのかどうか 間違い・アドバイスなどありましたら是非伺いたいと思います。 よろしくお願い致します。 ------------------------------------------------------------  シェルから起動されるJavaでバッチ処理を行うアプリケーションを  作成していまして、サーバマシンの複数のプロセスから起動されます。  (つまりjavaコマンドが複数回同時に実行されます)  1回の実行の間保持しておきたい値をstaticなクラス変数に格納しています。  そしてそれは、1回の実行の間はずっと同じなのですが、  プロセスごとに異なる値です 。  この時、この1回の実行の間に保持しておきたい"static"な変数は  次のプロセスから実行された時に書き換えられるのか?  という疑問がでたのが始まりです。  マルチスレッドの処理はありません。 ------------------------------------------------------------ 調べたところ、 ■1台で2つ以上のJavaアプリケーションを実行する場合、  それぞれのアプリケーションを個別にjavaコマンドで起動・・・  =>javaコマンド毎に"個別のJVMが"それぞれのプロセス上で動作する。 ■フィールドをstatic指定するとクラス変数となり、  ロードされたクラスごとに"JVM上に"1つしか存在しない変数となる。 ・以上の2点から、staticの変数がメモリ上で共有されるのは  1つのJVM(1プロセス)内での話しであり、他のプロセスから  その値を書き換えられる事はないと考えています。  そして、1プロセス内でのマルチスレッドな処理を行っている場合、  staticな変数の値は注意が必要だけど、  複数プロセスでシングルスレッドな処理を行っている場合、  (性能などの問題上staticにするかどうか良し悪しはあるとしても)  staticな変数の値の不整合について  考慮は不要と考えても宜しいのでしょうか? 経験が浅い為、確信が持てずにいる状況です。 宜しくお願い致します。

    • ベストアンサー
    • Java
このQ&Aのポイント
  • キリスト教は、世界的に広まった宗教であり、聖書を信仰の根拠としています。
  • キリスト教徒は、イエス・キリストを救世主と信じ、彼の教えに基づいて生活しています。
  • キリスト教の象徴である十字架は、イエス・キリストの犠牲と愛を象徴しています。
回答を見る