nowladingについて

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
たこやき

nowladingについて

#1

投稿記事 by たこやき » 15年前

マルチスレッドでCreatThreadでNowLoadingを作ろうとしてるのですが。ボタンを押してもnowLodingされません。どうしたらいいのでしょうか?ここだろうなというところを載せます。というかここしかないのですが。
DWORD sub(void)
{
while(lp==1)
{
//※変更してはいけない(ここから)---------
 g_pSprite->Begin(D3DXSPRITE_ALPHABLEND);
 //※変更してはいけない(ここまで)---------
// noloding画像描画
DrawBg(g_pSprite,&g_bgTexture1);
//背景描画の直後にマップ描画を行う。
      //※変更してはいけない(ここから)---------
      g_pSprite->End();
     //※変更してはいけない(ここまで)---------
}
return 0;
}
void DrawAll(void)
{
//※変更してはいけない(ここから)---------
g_pSprite->Begin(D3DXSPRITE_ALPHABLEND);
//※変更してはいけない(ここまで)---------
int n;
switch(g_systemMode)
{
case MODE_TITLE:
DrawBg(g_pSprite,&g_titelTexture);
DrawCommand(&g_commandPoint,&g_commandTexture);
Draw(&g_command,&g_tagTexture);
break;
case MODE_LOAD:
DWORD tid;
CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)sub,NULL,0,&tid);
n=0;
while(n<10000000)
{

[pre]				n++;
}
lp=0;
g_systemMode=MODE_STAGE;
break;
case MODE_STAGE:
描画処理
.
.
.
よろしくお願いします。

たこやき

Re:nowladingについて

#2

投稿記事 by たこやき » 15年前

すいません。間違いました。ボタンを押してもnowLodingされませんではなくwhile(n<100000000)通っても
nowlodingされません。while(n<100000000)の処理が終わるころに表示されます。です。

softya

Re:nowladingについて

#3

投稿記事 by softya » 15年前

気になる点をいくつか。
1.ウィンドウプロシジャの途中だと思われるDrawAllのwhile(n<10000000)で待っちゃいけません。
そもそも何で待っているか意味不明。
2.スレッドで描画するとややこしい事になるので、スレッドはロード処理にしてください。描画はウィンドウプロシジャ側に。(良く分かっている人なら、なんとでも成りますが)

>while(n<100000000)通ってもnowlodingされません。while(n<100000000)の処理が終わるころに表示されます。
メイン側で無限ループしてCPUを浪費しているのだから、スレッドが動作しないのは当たり前ですよ。
CPUを解放してください。

たこやき

Re:nowladingについて

#4

投稿記事 by たこやき » 15年前

そうなんですか。なんで待っているのかというと、大量のデータの読み込み処理の代わりに待っていたのですが、
意味がないのでしょうか?またなぜループと大量の読み込み処理の違いが出るのでしょうか?

たこやき

Re:nowladingについて

#5

投稿記事 by たこやき » 15年前

あと、Nowlodingを試す方法はないのでしょうか?質問ばかりですみません。

softya

Re:nowladingについて

#6

投稿記事 by softya » 15年前

>そうなんですか。なんで待っているのかというと、大量のデータの読み込み処理の代わりに待っていたのですが、意味がないのでしょうか?
whileでループ待ちするとCPUを優先的に使ってしまうので、スレッドや他のプロセスに処理が回らなくなります。これは、Windowsプログラミングで一番やってはいけないことです。

>またなぜループと大量の読み込み処理の違いが出るのでしょうか?
読み込み処理中は、HDDからの読み込み待ち時間がありますから、その間に他のスレッドやプロセスにタスクがスイッチングできます。

>あと、Nowlodingを試す方法はないのでしょうか?質問ばかりですみません。
読み込み処理をスレッド側にして、読み込み処理の代わりにSleep()で時間を浪費してください。Sleep中は他のスレッドに処理が移ります。メイン側にSleep()を入れるのはWindowメッセージの処理が出来なくなりますからやってはいけません。
メイン側への読み込み(スレッド)側の終了を通知するには、一番簡単なPostMessage()を使ってください。
なので、MODE_LOADからMODE_STAGEに切り替わるタイミングは、スレッドからPostMessage()で通知されたときとなります。MODE_LOAD中はNowLoadingを毎フレーム表示します。

たこやき

Re:nowladingについて

#7

投稿記事 by たこやき » 15年前

PostMessageを使わないで出来ないでしょうか?wndprocは別のファイルにあってブラックボックス状態なので。
メインにSLeep()を置いてはダメとはどこにやればいいのでしょうか?(sub関数に入れてみましたがダメでした)

softya

Re:nowladingについて

#8

投稿記事 by softya » 15年前

それじゃ終了フラグをvolatile型修飾子で。
int volatile SubThreadEndFlag = FALSE;
と宣言して、スレッドの終了時に
SubThreadEndFlag = TRUE;
としてください。
メイン側は、
if( SubThreadEndFlag ) {
g_systemMode=MODE_STAGE;
}
とやるのが安全だと思います。

>メインにSLeep()を置いてはダメとはどこにやればいいのでしょうか?(sub関数に入れてみましたがダメでした)
スレッドでSleepする分には大丈夫のはずですが?数秒ほどSleepさせてみてください。
ところでこの時、メイン側はCreateThread後すぐにリターンさせましたか?
(注意事項として、wndprocから呼び出された処理は必ず最大数ms程度でreturnする様にしてくださいね)

たいやき

Re:nowladingについて

#9

投稿記事 by たいやき » 15年前

ちょっとやりすぎたかもしれませんがSleep(10000)やりましたが、そしたらフリーズしてしまいました。
CreatThread後のリターンはここに記述してるとおりです。

softya

Re:nowladingについて

#10

投稿記事 by softya » 15年前

>CreatThread後のリターンはここに記述してるとおりです。

ここから
n=0;
while(n<10000000)
{
n++;
}

ここまでは、外さないとスレッドは動きませんよ。

これも言ったとおりに
g_systemMode=MODE_STAGE;
if文内に入れましたか?

>ちょっとやりすぎたかもしれませんがSleep(10000)やりましたが、そしたらフリーズしてしまいました。
ちゃんとスレッドを制御していたらSleep(10000)とスレッドでやってもフリーズする事はありません。

とりあえず今の状態のプログラムを張ってもらったほうが、問題が明確になると思います。

softya

Re:nowladingについて

#11

投稿記事 by softya » 15年前

あっともう少し改造しないとまずいですね。
MODE_LOADSTART:

MODE_LOADING:
に分けてください。
こんな感じです。

case MODE_LOADSTART:
// スレッドを起動する。
CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)sub,NULL,0,&tid);
g_systemMode=MODE_LOADING;

case MODE_LOADING:
//NOWLOADINGの表示処理

//スレッドが終了したら、モードを変更する。
if( SubThreadEndFlag ) {
g_systemMode=MODE_STAGE;
}
break;

たこやき

Re:nowladingについて

#12

投稿記事 by たこやき » 15年前

はい。わかろました。
DWORD WINAPI sub(void)
{
while(SubThreadEndFlag)
{
//※変更してはいけない(ここから)---------
g_pSprite->Begin(D3DXSPRITE_ALPHABLEND);
//※変更してはいけない(ここまで)---------
DrawBg(g_pSprite,&g_bgTexture1);

//※変更してはいけない(ここから)---------
g_pSprite->End();
//※変更してはいけない(ここまで)---------
}
return 0;
}
void DrawAll(void)
{
//※変更してはいけない(ここから)---------
g_pSprite->Begin(D3DXSPRITE_ALPHABLEND);
//※変更してはいけない(ここまで)---------
int n;
switch(g_systemMode)
{
case MODE_TITLE:
DrawBg(g_pSprite,&g_titelTexture);
DrawCommand(&g_commandPoint,&g_commandTexture);
Draw(&g_command,&g_tagTexture);
break;
case MODE_LOAD:
DWORD tid;
CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)sub,NULL,0,&tid);
n=0;
Sleep(100);
if(SubThreadEndFlag)
{
g_systemMode=MODE_STAGE;
}
		
[pre]			break;
case MODE_STAGE:

.
.
.
.
.

たこやき

Re:nowladingについて

#13

投稿記事 by たこやき » 15年前

更新しました。
DWORD WINAPI sub(void)
{

while(lp==0)
{

Sleep(1000);
}

SubThreadEndFlag = TRUE;
return 0;
}
void DrawAll(void)
{
//※変更してはいけない(ここから)---------
g_pSprite->Begin(D3DXSPRITE_ALPHABLEND);
//※変更してはいけない(ここまで)---------
DWORD tid;
switch(g_systemMode)
{
case MODE_TITLE:
DrawBg(g_pSprite,&g_titelTexture);
DrawCommand(&g_commandPoint,&g_commandTexture);
Draw(&g_command,&g_tagTexture);
break;

case MODE_LOAD:
//NOWLOADINGの表示処理
DrawBg(g_pSprite,&g_bgTexture1);
Sleep(1000);
lp=1;
//スレッドが終了したら、モードを変更する。
if( SubThreadEndFlag ) {
g_systemMode=MODE_STAGE;
}
break;

case MODE_LOADSTART:
// スレッドを起動する。
CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)sub,NULL,0,&tid);
g_systemMode=MODE_LOAD;
break;
case MODE_STAGE:

たこやき

Re:nowladingについて

#14

投稿記事 by たこやき » 15年前

更新しました。
DWORD WINAPI sub(void)
{
while(lp==0)
{
Sleep(1000);
}
SubThreadEndFlag = TRUE;
return 0;
}
void DrawAll(void)
{
//※変更してはいけない(ここから)---------
g_pSprite->Begin(D3DXSPRITE_ALPHABLEND);
//※変更してはいけない(ここまで)---------
DWORD tid;[/pre]
switch(g_systemMode)
{
case MODE_TITLE:
DrawBg(g_pSprite,&g_titelTexture);
DrawCommand(&g_commandPoint,&g_commandTexture);
Draw(&g_command,&g_tagTexture);
break;
case MODE_LOAD:
//NOWLOADINGの表示処理
DrawBg(g_pSprite,&g_bgTexture1);
Sleep(1000);
lp=1;
//スレッドが終了したら、モードを変更する。
if( SubThreadEndFlag ) {
g_systemMode=MODE_STAGE;
}
break;
case MODE_LOADSTART:
// スレッドを起動する。
CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)sub,NULL,0,&tid);
g_systemMode=MODE_LOAD;
break;
case MODE_STAGE:

たこやき

Re:nowladingについて

#15

投稿記事 by たこやき » 15年前

何とか解決しました。助言ありがとうございました。

閉鎖

“C言語何でも質問掲示板” へ戻る