HSPポータル
サイトマップ お問い合わせ


HSPTV!掲示板


未解決 解決 停止 削除要請

2008
1029
kenwaitで待っている間に他のプログラムを実行したい19解決


ken

リンク

2008/10/29(Wed) 12:21:10|NO.20480

以下のプログラムは二つのプログラムを簡略化したものですが、プログラムAのwait100で1秒
待っている間にブログラムBを実行したいのですがどのようにすれば良いか教えて下さい。
但しプログラムBの1ループは200ms〜2000msまで変化するものとします。


screen 1 title "プログラムB" screen 0 title "プログラムA" ////// プログラムA repeat 2 repeat 5 color 255,255,255:boxf pos 250,200 color:mes "処理1 実行中"+(5-cnt) wait 100;ここでプログラムBを実行したい loop repeat 3 color 255,255,255:boxf pos 250,200 color:mes "処理2 実行中"+(3-cnt) wait 100;ここでプログラムBを実行したい loop loop color 255,255,255:boxf pos 250,200 color:mes "終わり" stop /////// プログラムB gsel 1 repeat color 255,255,255:boxf pos 250,200 color:mes "処理3 実行中"+cnt await 200;〜2000 loop



この記事に返信する


SYAM

リンク

2008/10/29(Wed) 13:01:28|NO.20481

1秒待つ間に2秒かかる処理はできませんよね。
そのように遅れた場合には、Aの次の処理と並行してBの残りも処理したい ということでしょうか?



ken

リンク

2008/10/29(Wed) 15:06:13|NO.20483

>そのように遅れた場合には、Aの次の処理と並行してBの残りも処理したい ということでしょうか?
そういうことです。



f(浮気中)

リンク

2008/10/29(Wed) 16:56:28|NO.20484

HSPでスレッドが作れん以上、全部自分で管理するしか無かろうよ。

*lp
gosub *seq_a gosub *seq_b await 0 goto *lp *seq_a return *seq_b return
こんな感じかね?



f(浮気中)

リンク

2008/10/29(Wed) 17:12:43|NO.20486

・・・というか・・・

Aの1回目の5回のループ中、1000ms毎に1回づつ、
2回のめ3回のループ中に1000ms毎に1回づつ、
そのセットを2回だと?


1000ms毎に16回Bの処理を呼び出して、しかもBの処理は1回の処理に200から2000msかかるってか。


Bの処理が常に2000msかかった時はどうするんだ?
全部個別に処理するのか?

それとも必要回数処理できれば、Bの処理が自分の処理で送れる遅延は許されるのか?



pepe

リンク

2008/10/29(Wed) 22:54:22|NO.20492

このページは参考になりますか?

ttp://fs-cgi-basic01.freespace.jp/~hsp/ver3/hsp3.cgi?print+200707/07100036.txt
(h 抜きです。)



ken

リンク

2008/10/30(Thu) 10:01:23|NO.20494

ちょっと説明不足でした。実はBの処理は所々にwaitやawaitが入っていて一度に1loopを実行するもの
ではなく休み休みに1周する時間が条件によって約200ms〜2000msくらいかかるというものです。更に言うと
休み〜休みまでの最長処理時間(割り込みの効かない時間)は300ms以内です。

紹介いただいたURLはマルチスレッドのことですよね、一応マルチスレッドは調べたのですがWM_TIMERを使う
として2ヶ所のwait100の対処方法がわかりません。



f(浮気中)

リンク

2008/10/30(Thu) 10:58:08|NO.20495

await1でloop回すと無駄に時間かかるので、こっちに修正して貼り直し。

こうすりゃ1loopで処理できるべ。


#uselib "winmm.dll" #cfunc timeGetTime "timeGetTime" seq_a_ctl = 0 *lp stick st // シーケンスが待機状態で、スペースが押されたら実行開始 if ( st & 16 ) != 0 && seq_a_ctl = 0 : seq_a_ctl = 1 gosub *seq_a await 0 goto *lp *seq_a switch seq_a_ctl case 0 // 待機 swbreak case 1 // 処理1を行う mes "処理1実行" seq_a_ctl = 2 seq_a_tic = timegettime() + 1000 swbreak case 2 // wait1 if timegettime() >= seq_a_tic : seq_a_ctl = 3 swbreak case 3 // 処理2を行う mes "処理2実行" seq_a_ctl = 4 seq_a_tic = timegettime() + 2000 swbreak case 4 // wait2 if timegettime() >= seq_a_tic : seq_a_ctl = 5 swbreak case 5 // 作業終了、待機へ mes "作業終了" seq_a_ctl = 0 swend return



ken

リンク

2008/10/30(Thu) 17:27:58|NO.20503

f(浮気中)さんすみません、よく分らないのですが・・・

*lp〜goto *lpをプログラムBに組み込んで*seq_aの中にプログラムAを組み込むということですか?

Aのプログラムは待っている時間のほうが長いのでその間にBが走れば平行処理ができるのではないかと・・



f(浮気中)

リンク

2008/10/30(Thu) 22:30:38|NO.20512

いや、
*lp - goto *lpのループの中に、
gosub *seq_aを参考にして、gosub *seq_bとか作ればいいでそ。

で、seq_aの方でb側のシーケンスの開始を入れるようにすればいい。


ただし、b側が処理終わってるかどうかの判定も、その場合はどうするのかも考えなきゃいかん。
その辺は前に聞いたが、返答聞いて無いのでアドバイスのしようも無い。



ken

リンク

2008/11/1(Sat) 09:48:28|NO.20543

>b側が処理終わってるかどうかの判定も、
B側はプログラム起動から終了までloopしっぱなしなので終了するという考えはありません。
むしろBが実行している間にAを実行すると言った方が良いかもしれません。

Window上ではAもBもそれぞれ単独ならば同時実行できますがデーター(変数)を共有したいのでAとBを
統合して1つのプログラムにしたいのですが・・・



f(浮気中)

リンク

2008/11/1(Sat) 11:51:30|NO.20547

>B側はプログラム起動から終了までloopしっぱなしなので終了するという考えはありません。
むしろBが実行している間にAを実行すると言った方が良いかもしれません。


同じ事だと思うがなあ。
20495で書いたサンプルは理解できている?

Bがループしてるのなら、Bでループしながら、必要に応じてAの開始を入れれば良いだけだと思うんだが。
Bの側もSeq_aみたいな構造にしておかないといけないが。

まず、簡単な動作で、実験スクリプト書いてみ?
そんな難しい事じゃないぞ。どちらかと言うと面倒くさいだけで。



SYAM

リンク

2008/11/1(Sat) 11:51:40|NO.20548

>データー(変数)を共有したいのでAとBを統合して1つのプログラムにしたい

逆に、共有ができれば1つのプログラムにしなくてもいいってーのであれば、共有はできます。


#include "hspext.as" #include "hsp3util.as" aplsel "TESTPROGRAM",0 if (stat){ ;初回 x=rnd(ginfo_dispx) y=rnd(ginfo_dispy) vx=2 : vy=2 sdim infobuf screen 0,240,240,0,,,240,240 : title "おや" screen 2,64,32,2 : title "TESTPROGRAM" statictext infobuf,64,32 gsel 0 repeat x+=vx : y+=vy if ((x>=ginfo_dispx-1)|(x<=0)) : vx=vx*-1 if ((y>=ginfo_dispy-1)|(y<=0)) : vy=vy*-1 infobuf=""+x+"\n"+y gsel 2 : statictext_set 0,infobuf : gsel 0 title "おや - "+x+","+y gosub *DRAW wait 1 loop }else{ screen 0,240,240,0,,,240,240 : title "こ" sdim infobuf,64 notesel infobuf aplobj "Static",0 : if stat : dialog "情報取得失敗",1:end repeat aplget infobuf if infobuf="" : end noteget xstr,0 noteget ystr,1 x=int(xstr) : y=int(ystr) gosub *DRAW wait 1 loop } *DRAW redraw 0 color 0,0,0 : boxf if((ginfo_wx1<x)&(ginfo_wy1<y)&(ginfo_wx2>x)&(ginfo_wy2>y)){ pos x-ginfo_wx1,y-ginfo_wy1 color 255,255,255 : mes "●" redraw 1 } redraw 1 return

2つ以上起動してみてください。
1つめが親として座標を管理しています。
2つめ以降は、その座標を読み取って動作します。



f(浮気中)

リンク

2008/11/1(Sat) 11:59:39|NO.20549

よく見たら肝心な所の返答が抜けてるな。
AとBが入れ替わっただけで。

もう一度聞くが、
「じゃあ、BのループからAを実行しようとした時、Aが実行中だったらどうするのよ?」

呼び出した回数だけ、同時に並行処理するAが必要なのか?
呼び出した回数だけ、Aが実行されれば、並行処理しなくても良いのか?
呼び出した時にAが実行中なら、Aは処理しなくて良いのか?

それによっちゃやり方が変るぞ。



ken

リンク

2008/11/1(Sat) 17:46:14|NO.20554

f(浮気中)さんありがとうございます。

>同じ事だと思うがなあ。
そうですよね。

>20495で書いたサンプルは理解できている?
提示頂いたサンプルは処理1を実行して1秒たったら処理2を実行し更に2秒たったら終了しますよね。
こちらの希望は処理1を5回繰り返した後処理2を3回繰り返したいのですが、その場合case 1を5回
繰り返したらcase 2を3回繰り返せば良いということですか?だとすると
>seq_a_tic = timegettime() + 2000
の意味がわかりません。

>「じゃあ、BのループからAを実行しようとした時、Aが実行中だったらどうするのよ?」
この認識がちがうのかな、Bが実行中ということはAがwait100かstopしているときだけです。

>呼び出した回数だけ、同時に並行処理するAが必要なのか?
>呼び出した回数だけ、Aが実行されれば、並行処理しなくても良いのか?
>呼び出した時にAが実行中なら、Aは処理しなくて良いのか?
頭が混乱して何をどう答えれば良いのか分けが分らなくなってきた。並行処理はしたいのですが
処理はAが優先します。いやこう答えるとまた誤解を招くかな?

SYAMさんありがとうございます。

>逆に、共有ができれば1つのプログラムにしなくてもいいってーのであれば、共有はできます。
そうなんですか。aplselは使ったこと無いのでサンプル研究してデーターの受け渡し方を勉強してみます。

あっ、Aの処理1も処理2もカウントダウンとコマンド1発なので瞬時の動作です。だから殆んどwait100で
待っているだけです。



とおりすがり

リンク

2008/11/1(Sat) 23:23:56|NO.20563

APIのタイマーでも使えば?


#include "user32.as" //タイマー設定 oncmd gosub *Timer, 0x113 //WM_TIMER input a input b input c SetTimer hwnd, 1, 100, 0 SetTimer hwnd, 2, 200, 0 SetTimer hwnd, 3, 500, 0 stop *Timer switch wParam case 1 //100msで1回 objprm 0, a+1 swbreak case 2 //200msで1回 objprm 1, b+1 swbreak case 3 //500msで1回 objprm 2, c+1 swbreak swend return



f(浮気中)

リンク

2008/11/2(Sun) 03:00:11|NO.20567

>提示頂いたサンプルは処理1を実行して1秒たったら処理2を実行し更に2秒たったら終了しますよね。

そうね。


>こちらの希望は処理1を5回繰り返した後処理2を3回繰り返したいのですが、その場合case 1を5回
繰り返したらcase 2を3回繰り返せば良いということですか?だとすると

その辺は考えて組みなおしてくれないか。
俺は余程じゃない限り「まんま答え」なサンプルは出さん。
十分参考になるだろ。考えて作ってくれ。


>seq_a_tic = timegettime() + 2000
の意味がわかりません。

仮処理として、「処理1実行と表示」処理をして1000ms待機、「処理2実行と表示」処理をして2000ms待機しているだけだが。
timegettimeが意味不明と言うならググれ。次の処理へ移るまでのwait終了時間を、現在の時間から2000ms後と指定しているだけだ。
あくまで仮に提示しただけで、そちらが要望している「まんま」ではない。


>この認識がちがうのかな、Bが実行中ということはAがwait100かstopしているときだけです。
>頭が混乱して何をどう答えれば良いのか分けが分らなくなってきた。並行処理はしたいのですが
処理はAが優先します。いやこう答えるとまた誤解を招くかな?

OK,整理しよう。

・A処理とB処理がある。
・常時B処理ループが起動している。
・B処理ループは、A処理がwait中か、停止している間動作する。
・処理はA処理が優先する。

これで良いのか?

これだけなら、出したサンプルの機能だけで実現しそうにしか思えないのだが、
(むしろそのままの処理をしているようにしか見えないが)何が不足しているのか?



ken

リンク

2008/11/2(Sun) 22:34:16|NO.20581

皆さんありがとうございます。

>・A処理とB処理がある。
>・常時B処理ループが起動している。
>・B処理ループは、A処理がwait中か、停止している間動作する。
>・処理はA処理が優先する。

>これで良いのか?
その通りです。

皆さんのサンプルを参考に改造してみみました。(無駄が多いかと思いますが)
やりたいことは↓こんな感じです。だいぶ目的にかなってきたのですがプログラムAの1秒待ちは
プログラムBのif timegettime() >= seq_a_tic の問い合わせ位置によって1秒+Xmsオーバーし
ますよね。Aの処理回数が多くなると誤差が蓄積されるのでこれをなるべく正確にしたいのですが・・・


#uselib "winmm.dll" #cfunc timeGetTime "timeGetTime" ////// プログラムB screen 0,200,200 title "プログラムB" button gosub "start",*progA repeat color 255,255,255:boxf pos 50,100 color:mes "処理3 実行中"+cnt await 200;〜2000 if st & timegettime() >= seq_a_tic :gosub *seq1 if st2 & timegettime() >= seq_a_tic :gosub *seq2 loop ////// プログラムA *progA screen 1,200,200 title "プログラムA" st=1:count=5 *seq1 gsel 1 color 255,255,255:boxf pos 50,100 color:mes "処理1 実行中"+count if count=0:st=0:st2=1:count=3:gsel 0:return count-- seq_a_tic = timegettime() + 1000 gsel 0 return *seq2 gsel 1 color 255,255,255:boxf pos 50,100 color 255:mes "処理2 実行中"+count if count=0:goto *seq3 count-- seq_a_tic = timegettime() + 1000 gsel 0 return *seq3 color 255,255,255:boxf pos 50,100 color :mes "終わり" st=0:st2=0 gsel 0 return



f(浮気中)

リンク

2008/11/3(Mon) 00:55:37|NO.20589

これではっきりした。

処理A側が「実行中」にBからAの開始がかかった場合、
Aは現在の処理を破棄して最初から実行すればいいんだな。


というか、なんでswitch使ってるか理解はしてもらってなかったようだな。


#uselib "winmm.dll" #cfunc timeGetTime "timeGetTime" screen 0,200,200 : title "プログラムB" button gosub "start",*seq_a_trg screen 1,200,200 : title "プログラムA" now = timegettime() repeat gsel 0 color 255 , 255 , 255 : boxf color : pos 50,100 : mes "処理3 実行中" + cnt // 200ms(〜2000ms)待機 b_tic = now + 200 // 〜2000 while b_tic >= now now = timegettime() gosub *seq_a await 0 wend loop *seq_a_trg seq_a_ctl = 1 return *seq_a switch seq_a_ctl case 0 // 待機 swbreak case 1 // 初期化 seq_a_ctl = 2 seq_a_tic = now + 1000 seq_a_cnt = 5 swbreak case 2 // 処理1 gsel 1: color 255 , 255 , 255 : boxf color : pos 50 , 100 : mes "処理1 実行中" + seq_a_cnt seq_a_ctl = 3 swbreak case 3 // 処理1 時間待ち if seq_a_tic <= now : seq_a_ctl = 4 swbreak case 4 // 処理1 ループ seq_a_cnt-- if seq_a_cnt >= 0 { seq_a_tic = now + 1000 seq_a_ctl = 2 } else { seq_a_ctl = 5 } swbreak case 5 // 処理2 初期化 seq_a_tic = now + 1000 seq_a_cnt = 5 seq_a_ctl = 6 swbreak case 6 // 処理2 gsel 1: color 255 , 255 , 255 : boxf color 255: pos 50 , 100 : mes "処理2 実行中" + seq_a_cnt seq_a_ctl = 7 swbreak case 7 // 処理2 時間待ち if seq_a_tic <= now : seq_a_ctl = 8 swbreak case 8 // 処理2 ループ seq_a_cnt-- if seq_a_cnt >= 0 { seq_a_tic = now + 1000 seq_a_ctl = 6 } else { seq_a_ctl = 9 } swbreak case 9 // 終了 gsel 1 : color 255 , 255 , 255 : boxf color : pos 50 , 100 : mes "終わり" seq_a_ctl = 0 swend return

こうやって、B処理の待機中にA処理を呼び出し続ければ良い事じゃないか?



ken

リンク

2008/11/3(Mon) 18:22:54|NO.20597

f(浮気中)さん何回もすみません。

>Aは現在の処理を破棄して最初から実行すればいいんだな。
これは良いわけではありませんがボタンを押せないようにすれば良いのであまり気にしていません。

>なんでswitch使ってるか理解はしてもらってなかったようだな。
最初はWM_TIMERの割り込みで時間管理しようと思っていたのですが途中からtimegettimeに変更した
ら気が付いたらif・・・になっていた、後からこんな時こそswitch使うべきだったと・・・

とりあえずおかげさまで方向性は見えてきました。後はサンプルを元に2つのプログラムを結合すれば
良いだけです。

皆さんありがとうございました。
またよろしくお願いします。



ONION software Copyright 1997-2023(c) All rights reserved.