typedef struct{
HWND hwnd;BOOL th_end;HANDLE hmutex;
} DATA, *PDATA;
///////////////////////////////////////
static HANDLE hThread1,hThread2;
DWORD threadID1,threadID2;
static DATA data;
static HANDLE hMutex;
switch (msg) {
case WM_CREATE:
//hMutex=
//CreateMutex(NULL,FALSE,NULL);
data.hwnd = hWnd;
data.th_end = FALSE;
data.hmutex = hMutex;
hThread1=CreateThread(NULL,0,
(LPTHREAD_START_ROUTINE)Thread1,
(LPVOID)&data,
0,(LPDWORD)&threadID1);
hThread2=CreateThread(NULL,0,
(LPTHREAD_START_ROUTINE)Thread2,
(LPVOID)&data,
0,(LPDWORD)&threadID2);
/*x*/hMutex=
/*x*/CreateMutex(NULL,FALSE,NULL);
break;
とするのは正しくて/*x*/の行を削除して//をとり
hMutexの位置を前に持ってくるのは間違っているのでしょうか?
No.4ベストアンサー
- 回答日時:
> エラーもでず動作の違いも峻別できませんでした
Thread内のWaitForSingleObject()で失敗している
と思われますが、このサンプルでは戻り値のチェック
を行なっていません。スレッド間でリソースの競合が
発生していると思われます。
この回答への補足
#include <string>
using namespace std;
int i_th1,i_th2;
を追加しThread1&Thread2を
DWORD WINAPI Thread1(LPVOID pparam)
{
PDATA pdata;
HDC hdc;
string str;
char s[99];
pdata = (PDATA)pparam;
while (!pdata->th_end) {
WaitForSingleObject(pdata->hmutex, INFINITE);
hdc = GetDC(pdata->hwnd);
str="スレッド1:";str+=itoa(++i_th1,s,10);
TextOut(hdc,0,0,str.c_str(), str.size());
Sleep(500);
ReleaseDC(pdata->hwnd, hdc);
ReleaseMutex(pdata->hmutex);
}
return 0L;
}
DWORD WINAPI Thread2(LPVOID pparam)
{
PDATA pdata;
HDC hdc;
string str;
char s[99];
pdata = (PDATA)pparam;
while (!pdata->th_end) {
WaitForSingleObject(pdata->hmutex, INFINITE);
hdc = GetDC(pdata->hwnd);
str="スレッド2:";str+=itoa(++i_th2,s,10);
TextOut(hdc,0,20,str.c_str(), str.size());
ReleaseDC(pdata->hwnd, hdc);
ReleaseMutex(pdata->hmutex);
}
return 0L;
}
と変更したところ
後ろに宣言していたのではi_th1に対してi_th2が桁違いに大きくなっていきますが
前に宣言したらi_th1とi_th2はせいぜい1つ違いを保ちます
ということで作者のケアレスミスだと思われます
どうもありがとうございました
No.5
- 回答日時:
何回か質問を読み返しましたが、やっぱり私も何を目的とした質問か理解に苦しみます。
。。一応、回答しますが。。。
「HANDLE hMutex」と変数を宣言しただけでは何にも使えません。
CreateMutexで初めて有効な値を取得できます。その後、その値を使って排他などの制御できるようになります。
スレッドの方では渡されたDATA構造体のポインタを使用して排他制御しようとしているのか、変数がグローバールの値で、それを使用しているのかわかりませんが、どちらにしても最後にCreateMutexを行うのはロジック的にも理解できません。
あと、最後にCreateMutexして、グローバル変数のhMutexに代入し、各スレッドではその値を直接使っている場合だとしても、各スレッドの参照処理より前にCreateMutexが実行される保障はないのでご注意を。
タスクスイッチのタイミングによっては各スレッドの参照処理が先に動作することもあります。
CreateThreadの第5パラメータで、スレッドをサスペンドする必要性なども考慮する必要があります。
ありがとうございます
できれば
http://www.kumei.ne.jp/c_lang/sdk/sdk_92.htm
をアドレスにいて手見てミューテックスの宣言の部分を見ていただきたいのですが・・・
セカンドオピニオンを得られれば鬼に金棒ですから
よろしくお願いします
No.3
- 回答日時:
> CreateMutex 関数が返すハンドルには...ミューテックスオブジェクトのハンドルを要求する任意の関数で使うことができます。
裏を返せば、CreateMutex(あるいはOpenMutex)で得られたハンドルでなければ使えませんね。
> Mutexは宣言するだけでクリエイトしなくても使えるのか
やってみました?
この回答への補足
ありがとうございます
もちろんやってみました
動作を見ていても特に違いが分からないのです
http://www.kumei.ne.jp/c_lang/sdk/sdk_92.htm
にかかれているソースをBoralnd C++5.5
でコンパイルし実行してみましたがエラーもでず動作の違いも峻別できませんでした
No.2
- 回答日時:
> Mutexは宣言するだけでクリエイトしなくても使えるのか
> どうかということが分からないのです
...マニュアルには何と書かれているでしょうか?
この回答への補足
ありがとうございます
マニュアルには以下のようにかかれています
読解力と予備知識が欠如しているので関連部分について抽出し解説していただければ幸いです
CreateMutex 関数が返すハンドルには、新しいミューテックスオブジェクトへの MUTEX_ALL_ACCESS アクセス権が割り当てられていて、ミューテックスオブジェクトのハンドルを要求する任意の関数で使うことができます。
呼び出し側プロセスの任意のスレッドは、「wait functions」(待機関数)を呼び出す際に、ミューテックスオブジェクトのハンドルを指定できます。単一オブジェクトの待機関数は、指定されたオブジェクトがシグナル状態になると制御を返します。複数オブジェクトの待機関数に対して、指定されたオブジェクトの 1 つ(またはすべて)シグナル状態になったときに、制御を返すよう指示できます。待機関数が制御を返すと、待機中のスレッドは解放され、実行が継続されます。
ミューテックスオブジェクトは、どのスレッドにも所有されていない場合はシグナル状態になります。作成側スレッドは、bInitialOwner パラメータを使うと、既存のミューテックスの所有権を即座に要求できます。ミューテックスがスレッドに所有されている場合は非シグナル状態になり、呼び出し側スレッドがそのミューテックスの所有権を要求するには待機関数(WaitForSingleObject など)を使わなければなりません。その状態でミューテックスがシグナル状態になると、待機スレッドの 1 つに所有権が割り当てられ、そのミューテックスは非シグナル状態へ変化し、待機関数は制御を返します。特定のミューテックスを所有できるスレッドは、一度に 1 つだけです。所有権を解放するには、ReleaseMutex 関数を使います。
1 つのミューテックスを所有しているスレッドは、待機関数を繰り返し呼び出す場合に、自らの実行をブロックすることなく、そのミューテックスを指定できます。通常、同じミューテックスを繰り返し待機することはないはずですが、このメカニズムは、スレッドが既に自ら所有しているミューテックスを待機しようとしてデッドロックに陥ることを防止します。ただし、このスレッドが自らの所有権を解放するには、ミューテックスが待機の条件を満たすたびに、このスレッドから ReleaseMutex 関数を呼び出さなければなりません。
複数のプロセスが CreateMutex 関数を使って、同じ名前のミューテックスを作成することもできます。最初に実行されたプロセスはそのミューテックスを実際に作成しますが、2 番目以降のプロセスは既存のミューテックスのハンドルを開くだけです。この結果、複数のプロセスが同じミューテックスに対するハンドルを取得するので、ミューテックスを作成する特定のプロセスを決定して、そのプロセスを必ず最初に起動することを保証する必要がなくなります。この手法を使う場合、bInitialOwner パラメータで FALSE を指定してください。さもないと、どのスレッドが最初の所有権を取得したのか判断しにくくなることがあります。
複数のプロセスに同じミューテックスオブジェクトのハンドルを割り当てて、プロセス間同期の目的でそのオブジェクトを使うことができます。次のようなオブジェクト共有メカニズムを利用できます。
•CreateMutex 関数の lpMutexAttributes パラメータでミューテックスオブジェクトの継承を有効にしておくと、CreateProcess 関数が作成した子プロセスは、ミューテックスオブジェクトのハンドルを継承できます。
•プロセスは、特定のミューテックスオブジェクトのハンドルを指定して DuplicateHandle 関数を呼び出すことにより、ハンドルを複製できます。他のプロセスは、そのハンドルを使うことができます。
•プロセスは、OpenMutex または CreateMutex 関数を呼び出す際に、ミューテックスオブジェクトの名前を指定できます。
ハンドルを閉じるには、CloseHandle 関数を使います。プロセスが終了する際に、システムはそのプロセスが所有していたハンドルを自動的に閉じます。ミューテックスオブジェクトに対して 1 つまたは複数のハンドルが開いている場合、最後のハンドルが閉じた時点で、そのミューテックスオブジェクトは破棄されます。
No.1
- 回答日時:
> とするのは正しくて/*x*/の行を削除して//をとり
> hMutexの位置を前に持ってくるのは間違っているのでしょうか?
質問の意図は? そう考える根拠は何ですか?
この回答への補足
ありがとうございます
Mutexは宣言するだけでクリエイトしなくても使えるのかどうかということが分からないのです
Mutexが後ろにある場合はMutexをクリエイトする前にMutexを使ってます
要するにMutexは宣言しただけで使えて
必ずしもMutexを使う場合にはMutexをクリエイトするまで待ってMutexを使わなければならないのかということを知りたいのです
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・人生のプチ美学を教えてください!!
- ・10秒目をつむったら…
- ・あなたの習慣について教えてください!!
- ・牛、豚、鶏、どれか一つ食べられなくなるとしたら?
- ・【大喜利】【投稿~9/18】 おとぎ話『桃太郎』の知られざるエピソード
- ・街中で見かけて「グッときた人」の思い出
- ・「一気に最後まで読んだ」本、教えて下さい!
- ・幼稚園時代「何組」でしたか?
- ・激凹みから立ち直る方法
- ・1つだけ過去を変えられるとしたら?
- ・【あるあるbot連動企画】あるあるbotに投稿したけど採用されなかったあるある募集
- ・【あるあるbot連動企画】フォロワー20万人のアカウントであなたのあるあるを披露してみませんか?
- ・映画のエンドロール観る派?観ない派?
- ・海外旅行から帰ってきたら、まず何を食べる?
- ・誕生日にもらった意外なもの
- ・天使と悪魔選手権
- ・ちょっと先の未来クイズ第2問
- ・【大喜利】【投稿~9/7】 ロボットの住む世界で流行ってる罰ゲームとは?
- ・推しミネラルウォーターはありますか?
- ・都道府県穴埋めゲーム
- ・この人頭いいなと思ったエピソード
- ・準・究極の選択
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
CWnd::OnTimerのスレッドの取得
-
VB2005 シリアル通信のClose処理
-
スレッドにて同一メモリの書き...
-
メモリアクセスの競合について
-
クリティカルセクションの使用...
-
待機関数(WaitForMultipleObjec...
-
同一スレッドで、ロックをかけ...
-
マルチスレッドプログラミング...
-
VC++スレッドの正しい終了のさ...
-
スレッドの安全な終了のさせ方
-
.netアプリへのSendMessageでフ...
-
MFC通信プログラムマルチスレッ...
-
マルチスレッドでの画像描画
-
別スレッドのデータを受信できない
-
スレッドの終了を知りたい(Wind...
-
スレッドの終了はどうやるんで...
-
Macターミナルで実行中のプログ...
-
プロダクションコードとは?
-
3のつく数字と3の倍数のみを表...
-
c言語のサイコロを100回振って...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
WaitForSingleObjectの使い方に...
-
スレッドの監視方法について
-
Windows上で、シグナル(SIGTERM...
-
VC++スレッドの正しい終了のさ...
-
スレッドにて同一メモリの書き...
-
スレッドの安全な終了のさせ方
-
メインスレッドのPostMessageと...
-
C# スレッドから親ウィンドウへ...
-
別スレッドからメインダイアロ...
-
スレッドの終了はどうやるんで...
-
MFC通信プログラムマルチスレッ...
-
同一スレッドで、ロックをかけ...
-
VB2005 シリアル通信のClose処理
-
スレッドの終了の仕方
-
Linuxでスレッド優先度って変え...
-
LinuxでDoEvents()同等機能
-
C#でスレッド実行中のイベント...
-
msec単位のWait Timerが作れない!
-
スレッド終了を待つ間に開放さ...
-
win32 スレッドのハンドルついて
おすすめ情報