• ベストアンサー

マルチスレッドについて

現在”猫でもできる”の87、88章を学んでおります。 まず87章でマルチスレッドの根本的なやり方を学びましたが、いきなり疑問が浮かびました。 _beginthread関数によりスレッドをスタートさせ、この関数で登録した関数内で_endthread関数を実行し終了させていることは分かります。 しかし_beginthread関数で登録した関数に引数を渡す処理がどの部分で行われているのかわかりません。 登録する関数はvoid型で引数はvoid*型でなければいけないことは分かったのですが、プログラムのどこを見てもこの登録した関数に引数を渡す処理が行われていません。 その辺の動作の説明を分かる方でいいのでよろしくお願いします。 そして88章では排他制御のマルチスレッドを行うプログラムの製作を行っているのですが、ちょっとした疑問が浮かびました。 EnterCriticalSection関数、LeaveCriticalSection関数ではさまれたプログラムは排他制御され他からアクセスされない。 この関数はこんな理解で良いんですかね? この理解で行くと、88章で説明していきますが、子ウィンドウを2つ作成しそれぞれのプロシージャ内で排他制御された関数をスレッドとしてスタートしています。 この2つのスレッドの動作についてですが、互いに排他制御関数が記述されているため、動作としてはまず左の子ウィンドウのスレッドが処理されている場合、右の子ウィンドウのスレッドは停止している。そして左の子ウィンドウのスレッドの排他制御が解放されたときに、右の子ウィンドウのスレッドが開始する。 そしてあるとき左の子ウィンドウのクライアントウィンドウ内で右クリックされた場合、その時点で排他制御されたスレッドが終了するのを待ち、終了したらcountを+1する。 こんな動作が行なわれていると理解してよいのでしょうか?

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

  • ベストアンサー
noname#30727
noname#30727
回答No.6

ANo.5です。 >「1%の絶妙なタイミング」といっているのは極端に短い実行時間を持つ右スレッドが実行状態のときにクリックされた場合のことをいっているんですよね? その通りです。 とはいえ、カーネルはブラックボックスなので、あてにならない話として受け取っていただければと思います。

noconan
質問者

お礼

返信ありがとうございます。 色々と大変お世話になりました。 また何かしら疑問が発生した場合はお世話になるかもしれませんが、その場合はよろしくお願いします。 失礼します!

その他の回答 (5)

noname#30727
noname#30727
回答No.5

>よってたとえラウンドロビンとしても、クリックしたときに開始されるスレッドはランダムに発生するので、必ず同じ順に実行されることは考えられないと思います。 クリックされていない時に最も確率の高い「状態」は、左スレッドが無駄ループまたは描画をしていて、右スレッドがクリティカルセクション取得待ちをしている状態ですよね? 左スレッドがクリティカルセクションを取得してから解放するまでの時間に対して、右スレッドがクリティカルセクションを取得してから解放するまでの時間が100分の1だとしたら、99%くらいの確率で、その状態でクリックされる事になるはずです。 クリックされたときに作成されたカウントアップスレッドは、すぐに同じクリティカルセクションの取得待ちになるので、右スレッドとカウントアップスレッドは、同じ条件の待ち状態になります。 では、右スレッドとカウントアップスレッドは、どちらが先にクリティカルセクションを取得できるのか?というのが問題になるわけですよね。 クリティカルセクション取得の動作は、最初に極短時間のスピンロックを試みて、ロックできなければ通常のスレッドスケジューリングに切り替えるという事をしています。先の確立を前提とするなら、すでにクリティカルセクションを取得しているスレッドがあるので、ほぼ必ずスピンロックは失敗します。 そして、どちらが先に起きるのか?に戻ると、ラウンドロビンなら先に寝た方が先に起きるはずだというのが前の回答です。絶妙のタイミングというのはもちろん逆の1%の事です。 実際には99%以上の確立なのではないかと想像します。

noconan
質問者

補足

回答ありがとうございました。 少し難しかったですが、色々と丁寧に説明をいただき本当にありがとうございました。 このスレッドの状態遷移については、キューのようなものを想像すれば良いですね。 そして左スレッドが無駄に時間が長い処理を行っていることを気にかけずに考えてしまいましたorz そうですよね・・・・大半が左スレッドが実行状態で、他のスレッドは待ち状態になりますよね。 キューで考えるなら左から抜けていくとして [左スレッド][右スレッド][][][][] このような形を考え、今左スレッドが実行されているとするとキューの中は [右スレッド][][][][][] になり、次に実行されるスレッドが右スレッドであるのは確かですね。 この状態が大半を占め、その中でクリックされた場合キューの中は [右スレッド][カウントアップスレッド][][][][] このようになりますよね。 そして左スレッドが終了した時、ラウンドロビンを考え、キューの中は [カウントアップスレッド][左スレッド][][][][] このような状態になり、この状態の時には右スレッドが実行状態になっています。 このように考えると確かにカウントアップスレッドの次に来るスレッドは左スレッドということになりますね。 inthefloiさんが「1%の絶妙なタイミング」といっているのは極端に短い実行時間を持つ右スレッドが実行状態のときにクリックされた場合のことをいっているんですよね?

noname#30727
noname#30727
回答No.4

>加算するスレッドの終了直後左の子ウィンドウのスレッドが必ず開始される Windowsのスレッドは同一優先度ならラウンドロビンでスケジューリングされるはずなので、必ず同じ順番になってしまう事はありえます。 絶妙なタイミングで加算スレッドが起動されれば話は別ですけど。

noconan
質問者

補足

回答ありがとうございます。 プログラム実行時最初にラウンドロビンでスケジューリングされているのは左の子ウィンドウのスレッドと右の子ウィンドウのスレッドなのでスレッドの開始順序がそのあとのスレッドの実行順序を決定することはありえますが、しかしクリックしたときに発生するスレッドはラウンドロビンでも同じ順番とはならないんじゃないでしょうか? 「左の子ウィンドウのスレッド → 右の子ウィンドウのスレッド」  このように、ある時点でラウンドロビンから予想される次のスレッドが右の子ウィンドウのスレッドで、今現在実行状態になっているのは左の子ウィンドウのスレッドとした場合、 この時点でクリックされた場合左の子ウィンドウのスレッドが終了しだい、countを+1するスレッドが実行され、そのスレッドが終了すると右の子ウィンドウのスレッドが実行状態になるような状況が考えられます。 よってたとえラウンドロビンとしても、クリックしたときに開始されるスレッドはランダムに発生するので、必ず同じ順に実行されることは考えられないと思います。 絶妙なタイミングで加算スレッドが起動されれば話は別とアドバイスをいただきましたが、クリックした時に実行されるスレッドの次に実行されるスレッドが必ず左の子ウィンドウのスレッドになることもかなり絶妙なタイミングだともいえます。 やはりこれは難しい問題なのでしょうか? 確かにこの2つのスレッドは1つの共有変数にアクセスはしていますが、スレッドの開始命令をだしているのはそれぞれ別々のプロシージャで、左の子ウィンドウのクライアントウィンドウでクリックしたときのみ、countを+1加算するスレッドが実行されます。この辺にヒントがあるように感じるのですが・・・・

  • 1839cc
  • ベストアンサー率54% (12/22)
回答No.3

WaitForSingleObjectによってmutexを所有する処理も行っています。 もし、WaitForSingleObjectが単純に待機するためだけの関数だとすれば、待機から抜けて所有権を取得するまでの間に、他スレッドが所有権を取得してしまうかもしれません。 ですので、待機と所有権の取得は、ひとつのシステムコールで終了する必要があるのです。 APIのネーミングが不親切なのですが、このAPIはかなり汎用的なので、Waitというネーミングが適切だったようです。

noconan
質問者

補足

回答ありがとうございます。 すいません ちょっと長くなるので補足の部分に記述させてもらいました なるほど、WaitForSingleObject関数は待機と所有する処理を行っているのですね。確かに待機と所有を1つの処理で行わなければ、ある意味所有権を違うスレッドにずっと取られっ放しということだってあるかもしれないですからね。 しかし申し訳ないのですが、またまた疑問が浮かんできました。 あるいみ"mutex"と"CriticalSection"は同じ処理が目的のように考えられるのですが、CriticalSection関数についての疑問です。 88章では3つのスレッドを作成し、そのスレッドごとにCriticalSection関数を記述しているため、ある時点で実行しているスレッドは必ずひとつということになります。実際この章のプログラムを作成すると、クリック時には2つのウィンドウにクリック回数が誤差なく表示されますが、ここで疑問が浮かびました。 実際細かい動作を書くと、左の子ウィンドウのクライアント領域をクリックした場合に、2つの子ウィンドウのクライアント領域にクリック回数が表示されるのですが、左の子ウィンドウのスレッドではCriticalSectionに入ってから多少時間がかかる処理をわざと行い、その後に共通変数countへアクセスし、回数を表示しています。これはきちんと同期が行われているかを確かめるために行っているのですが、これはあくまでクリックされてからスレッドの共通変数countを+1加算するスレッドが終了した直後に実行されれば、確かにクリックした後に多少時間がかかってから表示が更新されますが、共通変数を+1加算するスレッドの直後に、左の子ウィンドウのスレッドではなく、右の子ウィンドウのスレッドが来るということも考えられないでしょうか? 長くなってしまって申し訳ないですが、まとめると このプログラムを実行するとクリックした後、多少時間がかかってから2つの子ウィンドウの表示が更新されます。これはクリックした後に共通変数countを+1加算するスレッドが開始され、そのスレッド終了直後左の子ウィンドウのスレッドが開始されるためです。しかし、自分ではこの処理が納得できず、共通変数countを+1加算するスレッドの終了直後右の子ウィンドウのスレッドが開始される場合があるのではないだろうかと考えています。 もしこの考えのように共通変数countを+1加算するスレッドの終了直後、右の子ウィンドウのスレッドが開始された場合、表示の更新処理にたいして同期することができないのではないかと考えています。しかし、プログラムを実行した場合かならず同期されて表示が更新されます。 これは自分の考えが間違えているからでしょうが、自分の考えのどの部分が違うのかが分かりません。 まぁ単にこの疑問は「共通変数countを+1加算するスレッドの終了直後左の子ウィンドウのスレッドが必ず開始される」とすれば納得できるのですが、どうしてもこんな確約はできないと思うのですが・・・・・ アドバイスをよろしくお願いします。

  • Oh-Orange
  • ベストアンサー率63% (854/1345)
回答No.2

★引数を渡す処理は WndProc の『WM_CREATE』にあります。 ・そのまま『_beginthread( ThreadMain, 0, &val );』と記述されている『&val』が引数です。  この構造体は、第87章ページの上のほうにある構造体です。→自分で定義したもの。  ウィンドウプロシージャ『WndProc』の定義のすぐ下にも >最後の引数はスレッドに渡されるデータのアドレスです。  という解説があります。→よく読むと見つかりましたよ。 ・なお、_beginthread 関数でスレッド用のコールバック関数『ThreadMain』を登録しているので  以後、ThreadMain() 関数に自分で定義した val 構造体 が void* 型で渡されます。→これはシステムが  渡しますので引数の受け渡しは気にする必要はありません。そのために、_beginthread 関数の第1引数と  第3引数でスレッド処理(コールバック関数)とデータ構造体を関連付けているのです。 ・子ウインドウの場合も同じく『_beginthread( Thread, 0, &val );』の『&val』が引数です。  ただし、val 構造体にセットするウインドウハンドルは、子ウインドウのハンドルです。  これ以外は、メインのプロシージャ『WndProc』にある『WM_CREATE』と同じです。 ●第88章について ・排他制御を行うために EnterCriticalSection 関数~ LeaveCriticalSection 関数でプログラムを  挟むと他のスレッドは『待避状態』となりアクセスできなくなります。これを分かりやすく解説  されているリンクを下に張ります。ここでは『排他制御』のある、なしについて載っています。  http://ja.wikipedia.org/wiki/%E3%82%AF%E3%83%AA%E3%83%86%E3%82%A3%E3%82%AB%E3%83%AB%E3%82%BB%E3%82%AF%E3%82%B7%E3%83%A7%E3%83%B3 ・共通変数に対するスレッドの同時アクセスを防ぐ仕組みですね。つまり、  左ウインドウのスレッドが動作中に  右ウインドウのスレッドが開始されても『待避状態』で停止しています。  そして、左ウインドウのスレッドが終了すると排他制御も解放されるため、  待機中だった右ウインドウのスレッドの処理がここで開始します。  以後、排他制御が解除されるまで別のスレッドが開始しようとしても『待避状態』で待たされます。 最後に: ・第88章については noconan さんの理解されている通りであっています。  複数のスレッドで共通のグローバル変数などにアクセスした場合に、排他制御で同期を取るための処理ですね。 ・あと『猫でもわかるプログラミング』というサイトのリンクなどを貼っておくと知らない人でも適切な  アドバイスが出来るようになります。その上で第87章、第88章…と質問して下さい。 ・以上。おわり。

参考URL:
http://ja.wikipedia.org/wiki/クリティカルセクション
noconan
質問者

お礼

適切な回答ありがとうございました。 細かい説明のため、疑問が解決されすっきりしました^^ しかも動作が分かりやすく時系列で書かれた排他制御のプロセスが示されたサイトまで紹介いただきありがとうございます。 とても分かりやすかったです。 そしてリンクを貼るのは確かに有効ですね。 これからはそうしようと思います! ついでにちょっと違う質問をしてもよろしいでしょうか? 92章についてです。 この章ではmutexについて行っていますが、またまた疑問が出てきてしまいました。 まず複数のスレッドに対する共通のmutexをメインウィンドウ側で生成します。 スレッド側では初めにWaitForSingleObject(pdata->hmutex, INFINITE); を実行し、スレッドが終了するときに ReleaseMutex(pdata->hmutex); を実行してmutexを解放しています。 具体的な動作はmutexが解放されるまでWaitForSingleObject関数で待機状態にし、mutexが解放されたらWaitForSingleObject関数の記述以降のプログラムが処理されるという動きになると思うのですが、ここで疑問が出てきます。 ReleaseMutex関数によりmutexの解放を行うのはわかるのですが、mutexを所有する処理はどこで行っているのでしょう? もし分かるようならお教えお願いします。

  • 1839cc
  • ベストアンサー率54% (12/22)
回答No.1

その書籍を持っていないため、一つ目の質問に対してのみの回答をさせていただきます。 スレッドに渡す引数は、_beginthread の第三引数に指定されていませんか? 実際にパラメータとして渡す処理は _beginthread 内部で行われています。

noconan
質問者

お礼

回答ありがとうございました。 変な質問をしてしまってすみません。 確かに第三引数で指定していましたね・・・・

関連するQ&A

  • マルチスレッド化。

    今とても大きな配列を使用し、長時間処理をするプログラムを組んでいます。元々処理時間に1時間を要するプログラムを2分で処理を完了するまでに仕上げました。 しかし、探究心はおさまらずもう少し高速化に挑みたいと考えています。 過去に「猫でもわかる」のSDK第1章と2章を学び、マルチスレッドのプログラムをSDKで組んだことがあります。それを利用してマルチスレッド化を実現したいと考えています。 言語はCでVisualStudio2005を使用しています。 *疑問1   SDKの場合WinMain関数とプロシージャからの実行で_beginthread関数を記述すれば処理が開始されます。 Cでもmain関数内に記述すれば、SDKと同様に処理できるのでしょうか? *疑問2 _beginthread関数の引数に関してです。 第1引数にvoid型のスレッド関数、第2引数に0?、そして第3引数にはスレッド関数に渡すデータの引数を記述すると把握しているのですが、渡したいデータは複数あり、***型と**型、それに変数を数個とスレッド関数に渡したいデータだらけなのですが、どのように記述すればよいでしょう? *疑問3 2つのスレッドを作成しようと考えていますが、その2つのスレッドで1つの大きな配列を共有して処理したいと考えています。 そのため、スレッド間の同期が必要になるわけですが同期の種類にもクリティカルセクションやミューテックス、イベントと豊富でどれを使用すれば良いのか迷ってしまいます。厳密に同期を取り処理をするにはイベントが一番良いと考えています。 これらの疑問に答えられる方はアドバイスをよろしくお願いします。

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

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

  • メンバ関数(メソッド)をマルチスレッドにしたい

    環境はWinXPでVisual Studio 2005を使用しています。 C言語で関数をマルチスレッド化するにはこんな感じでOKでした。 // マルチスレッド関数 void Thread( void * ) { } void MainFunc() {   (HANDLE)_beginthread( Thread, 0, NULL ); } こんな風にスレッド関数をC++のメソッドに変えてうまくいくかと思い class Test_c { public:   void Thread( void * ); } ; // マルチスレッド関数 void Test_c::Thread( void * ) { } void MainFunc() {   Test_c t t;   (HANDLE)_beginthread( t.Thread, 0, NULL ); } とするとエラーが出てきてしまい、コンパイルが通りませんでした。 C++のメンバ関数をマルチスレッド関数としたい場合はどの様に書けばよいのでしょうか・・?

  • プログラムのマルチスレッド化について。

    マルチスレッド化したプログラムの作成を行いたいと思い、 前に作った、スライス画像を作成するプログラムを マルチスレッド化しようと、自分作ってみたのですが、デバック中に エラーで、止まってしまいます。 プログラムはこれです。http://koushi12.if.land.to/main.h この中の、///ここでエラーがでます/// というところで止まってしまいます。 ちょっと長いので、もしお時間ある方いらっしゃっいましたら見ていただき、修正箇所を指摘していただきたいのですが、 プログラム読むほど時間無い方には、質問で答えて頂きたいのですが、 各スレッドに、データ(引数)を渡すところで、 1つのデータ(例えばポインタで作ってある、画像データ)を、2つのスレッドに渡しても大丈夫なのでしょうか? データは、2つ作って、それぞれを、それぞれのスレッドに渡さないとダメなのでしょうか? それと、例えば、出力関数などを1つだけ作ってあったとして、 それを、各スレッドの中で、呼び出して大丈夫でしょうか? 関数も、各スレッドが呼び出しで衝突しないように、2つ作る必要があるのでしょうか? すみませんが、回答よろしくお願いします。

  • (マルチスレッド)_beginthreadexに複数の引数を渡す

    現在プログラムでマルチスレッドをやろうとしているのですが、 マルチスレッドの関数に数値や配列などの引数を渡すことは可能でしょうか? MSDNで調べてみると、_beginthreadex関数の4番目のNULLのところに引数リストを 指定できるとあったのですが、その意味が良くわかりませんでした。 以下のプログラムの場合にマルチスレッドに変数a, b, cを引数として渡したい場合は どのように書けばいいのでしょうか? #include <stdio.h> #include <windows.h> #include <process.h> unsigned WINAPI MyThread( void *lpx ){ while (1) { printf("スレッド実行中\n"); Sleep(1000); } return 0; } void main(){ // スレッドに渡したい変数の宣言 int a = 128; int b = 256; int c = 512; // スレッドIDの宣言 DWORD thID; // マルチスレッドの開始 (HANDLE)_beginthreadex( NULL, 0, &MyThread, NULL, 0, (unsigned int*)&thID ); // ループ while (1) { printf("メイン関数実行中\n"); Sleep(2000); } }

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

    MFCマルチスレッドについて COMやIOボードからの入力に応じて動作するアプリを作っています。 AfxBeginThreadにてそれぞれワーカスレッドを作成しCOMやIOから入力があれば AfxBeginThreadを呼んでいるクラスにあるメンバ関数を実行しようとしています。 AfxBeginThreadにて*thisを送り、制御関数内で、mycls->OnButton***()というような 感じで現在は作っています。(OnButton***になっているのはデバッグ用にボタンで あらかじめ作成している関数のためです。) このときに、mycls->OnButton***()は親スレッドで動いていると考えていいのですか? あくまで親スレッドのクラスのメンバ関数を制御関数が動いている子スレッドで実行 しているだけなのでしょうか? 実は、ログ表示のため制御関数の中(受信データを表示)と、mycls->OnButton***()の中 (作業結果を表示)に同じエディットコントロールへの表示部分があります。 表示部分の処理は、いったんCStringで読み込んできて最大文字数チェックを行い、 再度文字数を調節して書き直しということをやっているため、一応クリティカル セクションにはしているのですが、実際どう動いているか分からないため、やり忘れ ていることや、やってはいけないことをやってそうです。 すいませんがご教授願います。

  • マルチスレッドプログラミングについて

    現在DirectXでマルチスレッドを使ってプログラムを組んでいますが、その処理の中で描画のみを切り離してスレッド化しようと思っています。 そこで質問ですが、描画スレッドに渡す処理の個数が多い場合は描画スレッドを2つにして処理する個数も分けたほうが処理は早くなるのでしょうか?

  • マルチスレッド

    ウインドウズプログラミングを始めて1ヶ月弱の初心者です。 色々探してみたのですが、結局良く分かりませんでした。 宜しくお願いします。 以下のリンクにおいて、 http://wisdom.sakura.ne.jp/system/winapi/win32/win143.html 1)主スレッドとは、具体的にソースファイルのどこからどこまでのことを言うのでしょうか? そもそもスレッドとは何でしょうか?関数のことでしょうか? また、タスクとは、実行ファイルと考えて良いのでしょうか? 2)副スレッド(ThreadFunc)を作成すると、主スレッド(WinMain?)と副スレッドで並列処理をするとのことですが、CPUは普通一つしかないので、実際は、主スレッド(WinMain?)と副スレッドを常に切り替えながら動作すると思います。が、ここで疑問なのですが、主スレッドと副スレッドの切り替えはいつ誰が行うのでしょうか?また、切り替えタイミング(例えば1ms毎に切り替えたいとか)は自由に設定出来るのでしょうか? 3)"マルチスレッドは親プロセスのメモリ空間を共有します" とあるのですが、これは CreateThread(NULL , 0 , ThreadFunc , (LPVOID)hWnd , 0 , &dwID) の(LPVOID)hWnd を、副スレッド(ThreadFunc)に引数として渡しているから、つまり、主スレッドと副スレッドは、(LPVOID)hWnd だけがメモリを共有する、ということでしょうか? 主スレッドと副スレッドでメモリを共有すると、どんなメリットがあるのでしょうか? 4)マルチスレッドはこういう時に使うとよい、 というような大まかな判断基準があれば教えて下さい。 分かり辛い質問で申し訳有りません。宜しくお願い致します。

  • マルチスレッド内のループについて

    こんにちは。 開発環境は VC++6.0 SDI マルチスレッドがあり、2つの処理を行う関数が書かれています。 このスレッドはダイアログボックスに配置したストップボタンを押すとフラグFALSEになりループを終了させます。 2つの関数は、int型の整数を引数にして、処理を行います。 整数はある値に達すると 0 になり永遠にループを続け、2つの処理を行います。 と言う意味合いでプログラムを書きました。(書いたつもりです) (1)この書き方ですと、for内のループが動いている時に、右上の×ボタンでダイアログを閉じると [Debug Assertion Failed!]と言う警告文が出て強制的に終了してしまいます。 ストップボタンを押してもcount=10になるまではループしています。(当然ですが・・。) そもそもマルチスレッドの中にこのような形でfor文を入れるのは間違っているのでしょうか? どのような書き方にすれば良いのでしょうか? よろしくお願い致します。 bool m_flags;//スレッド内の処理を続けるか示すフラグ UINT CabcDlg::thread(LPVOID pParam)// { CabcDlg *pInst = (CabcDlg *) pParam; while(pInst->m_flags){//ストップボタンが押されると終了する。 for (int count = 0; count<10; count++ ) { pInst->OnSend(count); //処理A pInst->OnReceive(count);//処理B } } return 0; }

  • C++マルチスレッド処理について

    こんにちは 現在スレッドを作成して,マルチスレッド処理をしようとしているのですが, 全然理解できないので皆様のお力をお貸し下さい。 やりたい事は, (1) メインスレッドからスレッド1を作成。 (2) スレッド1では,ひたすらファイルなどからデータを取得させる。(読み込めなくなるまで) (3) メインスレッドでは,時々スレッド1を止めて,再度処理を続行させたい。 class Sample { public: // Sampleオブジェクト作成,同時にスレッド1を作成 Sample* create(); // スレッド1を止めて,再度動かす void process(); private: // この関数をスレッド1で処理させる // 内部では,読み込めなくなるまで無限ループ? void get(); }; スレッドに関してはイメージが湧くのですが, mutex (必要ですか?) に関しては一向に理解できません。 何を排他制御するのでしょうか。オブジェクト? 関数? 複雑ではなさそうなのですが,今までシングルスレッドの処理のみ書いていたため ピンときません。 よろしくお願い致します。

専門家に質問してみよう