🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
マルチスレッド

マルチスレッドは、どのように機能がコンピュータによって実行したのかを、(一般的にはスレッドとして参照される)実行の複合的な共同作用するストリームへ区分することが出来ます。

Processing

Processingは、オープンソースプロジェクトによるCGのためのプログラミング言語です。Javaをベースにしており、グラフィック機能に特化しています。イメージの生成やアニメーションなど、視覚的なフィードバックを簡単に得ることが可能です。

Q&A

解決済

1回答

444閲覧

サブスレッドにて0.5秒毎に値が変わってくれない

P5_USER

総合スコア73

マルチスレッド

マルチスレッドは、どのように機能がコンピュータによって実行したのかを、(一般的にはスレッドとして参照される)実行の複合的な共同作用するストリームへ区分することが出来ます。

Processing

Processingは、オープンソースプロジェクトによるCGのためのプログラミング言語です。Javaをベースにしており、グラフィック機能に特化しています。イメージの生成やアニメーションなど、視覚的なフィードバックを簡単に得ることが可能です。

0グッド

0クリップ

投稿2019/11/09 07:10

いつもお世話になっています。

前提・実現したいこと

(1を押したとき、)サブスレッド内で背景を永続的に0.5秒毎に黒と緑にしたい。

発生している問題・エラーメッセージ

実行時、緑→黒になった後、緑になってくれない。
コンソール部分にはI am Sleeping...と1秒毎に表示してくれているのですが...

該当のソースコード

processing

1SubThread sample = null; 2 3float G = 255; 4 5void setup() { 6 size(500, 500, FX2D); 7 textSize(16); 8 textAlign(LEFT, TOP); 9} 10 11void draw() { 12 //background(200); 13 background(0, G, 0); 14 fill(0); 15 text("I am Main Thread.", 8, 0); 16 17 if ( sample != null && sample.running ) { 18 // サブスレッドが実行中 19 text("Sub Thread is Running.", 8, 20); 20 } else { 21 // サブスレッドは停止中 22 sample = null; 23 } 24} 25 26void keyPressed() { 27 if ( key == '1') { 28 // サブスレッド停止中なら生成する 29 if ( sample == null ) { 30 // サブスレッドクラスを生成 31 sample = new SubThread(); 32 //Threadクラスを生成 33 Thread subThread = new Thread(sample); 34 //実行開始 35 subThread.start(); 36 } 37 } else if (key == '0') { 38 // サブスレッド実行中なら停止を依頼する 39 if ( sample != null && sample.running) { 40 sample.stopRunning(); 41 } 42 } 43} 44 45class SubThread implements Runnable { 46 // 実行許可FLG 47 private boolean running = true; 48 49 // ここが実行される 50 @Override 51 public void run() { 52 while (running) { 53 try { 54 //G = 255; 55 //G = 0; 56 println("I am Sleeping..."); 57 Thread.sleep(1000); 58 } 59 catch( InterruptedException ex) { 60 ex.printStackTrace(); 61 } 62 // 点滅間隔|0.5[sec] 63 if (frameCount / (frameRate * 0.5) % 2 ==0) { 64 G = 255; 65 } else { 66 G = 0; 67 } 68 } 69 70 println("Sub Thread exit"); 71 } 72 73 public void gValue() { 74 } 75 public void stopRunning() { 76 running = false; 77 } 78} 79

試したこと

マルチスレッドについては、
http://mslabo.sakura.ne.jp/WordPress/make/processing 逆引きリファレンス/マルチスレッドを実現するには/
を参考にしています。

補足情報(FW/ツールのバージョンなど)

processing3.4

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

恐らくですが、以下のコードでframeCount / (frameRate * 0.5)の部分の計算が浮動小数点数(float)での演算となり、% 2の結果がちょうど 0 となる機会が無いのだと思います。その為にスイッチせず、常に黒(G=0)になってしまうのかと。

Processing

1 if (frameCount / (frameRate * 0.5) % 2 ==0) { 2 G = 255; 3 } else { 4 G = 0; 5 }

int型にキャストしたらどうでしょうか。if (int(frameCount / (frameRate * 0.5)) % 2 == 0)


追記しました:2019-11-09 21:37

動作を確認させていただきました。ご提示のコードをよくよく拝見すると、0.5秒ごとに点滅する意図であるものの、その前にThread.sleep(1000);とのように1000ミリ秒スリープしているので、点滅間隔は常に1秒になってしまいます。まず、ここを100ミリ秒にします。更に、先の私の回答でif (int(frameCount / (frameRate * 0.5)) % 2 == 0)int型にキャストする部分をif (int(frameCount / (frameRate * 0.5) % 2) == 0) と修正し、最終的にSubThreadクラスのrunメソッドを以下のようにしたところ、500ミリ秒ごとに緑・黒・緑・黒・・・と点滅するようになりました。

Processing

1 public void run() { 2 while (running) { 3 try { 4 //G = 255; 5 //G = 0; 6 println("I am Sleeping..."); 7 // 100ミリ秒待機 8 Thread.sleep(100); 9 } 10 catch( InterruptedException ex) { 11 ex.printStackTrace(); 12 } 13 // 点滅間隔|0.5[sec] 14// if (frameCount / (frameRate * 0.5) % 2 ==0) { 15 if (int(frameCount / (frameRate * 0.5) % 2) == 0) { 16 G = 255; 17 } else { 18 G = 0; 19 } 20 } 21 22 println("Sub Thread exit"); 23 }

投稿2019/11/09 07:32

編集2019/11/09 12:38
dodox86

総合スコア9256

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

P5_USER

2019/11/09 08:46

dodox86さん 回答ありがとうございます。 ご提案いただいた方法ですが、結果は変わりませんでした......
dodox86

2019/11/09 09:00

そうでしたか。申し訳ありません。実際、どのような値になりましたか? G=0のelse 節に必ず入ってきているのではないでしょうか。
dodox86

2019/11/09 09:07

{G=255}と{G=0}のそれぞれに節に必ず入っているのであれば、描画の問題となります。
P5_USER

2019/11/10 02:11

返信が遅くなりました。 追記頂いたところを見ました。 実際に動かしてみると、 1をキーインしてから約10秒後にテンポが速まったりするのですが、 そちらでも同様の現象が発生していましたか。
dodox86

2019/11/10 07:10 編集

> 1をキーインしてから約10秒後にテンポが速まったりするのですが、そちらでも同様の現象が発生していましたか。 再度確認しましたが、当方の環境ではそのような現象は発生しませんでした。ずっとおおむね0.5秒間隔で点滅しています。ただ、次のようなコードでframeCountとframeRate の値を確認してみると分かるのですがframeRateは必ずしも一定とはなりません。 println("frameCount=" + frameCount + ", frameRate=" + frameRate); if (int(frameCount / (frameRate * 0.5) % 2) == 0) { 実行例一部: frameCount=624, frameRate=60.02612 I am Sleeping... frameCount=630, frameRate=60.003532 I am Sleeping... frameCount=636, frameRate=59.998253 I am Sleeping... ほぼ60fpsですが、微妙にズレます。これから考えると、きれいに0.5秒間隔でON/OFFされないケースがありそうです。このあたりはPC環境に依存すると思います。提示させていただいたコードは質問者さんであるP5_USERさんのコードを踏襲したつもりのものでしたが、このコードに限って言えば、 Thread.sleepで100ミリ秒なり500ミリ秒なり待たせる限り、そのコードで100ミリ秒なり500ミリ秒が確保されているので、フレームレートから0.5秒間隔を割り出すのではなく、単にフラグのN/OFFや日時情報のようなもので制御するかたちでも良いと思います。
dodox86

2019/11/10 07:22

。。。と思ったら、長時間動作させていると0.5秒間隔の点滅がタイミングがズレてきていますね。(<速くなったりしている)frameRate自体が60fpsピッタリではないので、frameRateから0.5秒間隔間隔を割り出すのは不安定な気がしています。
P5_USER

2019/11/10 08:17

調査ありがとうございます。 確かに、働いているマシンにもピンキリがあることを考えると、 frameRateで時間を計るのは避けた方がよさそうですね。 日時情報はイメージしやすいのですが、 フラグのON/OFFというのは具体的にはどのようなモノでしょうか。 ラッチ回路的なモノでしょうか。
dodox86

2019/11/10 08:27

> フラグのON/OFFというのは具体的にはどのようなモノでしょうか。 > ラッチ回路的なモノでしょうか。 そうですね。単純に、以下のようなものを想定しています。500ミリ秒スリープさせ、それを周期としますが、フラグ変数toggleでスイッチします。 public void run() { boolean toggle = true; while (running) { try { println("I am Sleeping..."); Thread.sleep(500); } catch( InterruptedException ex) { ex.printStackTrace(); } if (toggle) { G = 255; } else { G = 0; } toggle = !toggle; } println("Sub Thread exit"); }
dodox86

2019/11/10 08:32

ただ、ゲームやCG等、複雑な描画をするようなプログラムに発展するのであれば、反対にframeRateを意識してプログラミングするのはありだと思います。目的次第ですね。
P5_USER

2019/11/11 01:02

ご丁寧にありがとうございました。 toggleを使ったものが、単純かつ必要十分でした。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問