質問をすることでしか得られない、回答やアドバイスがある。

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

ただいまの
回答率

90.49%

  • C++

    3581questions

    C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

優先度の処理について

解決済

回答 3

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 979

aoshanghai

score 18

仕事で、LEDを光らせる処理をC++で書いておりました。
通常は、定期的にLEDをオンオフさせる単純な光り方をさせているのですが、押されたボタンによって、優先度を高くして、ピカピカといった形で激しく光らせないといけません。
優先度は、低、中、高の3つを用意しておりました。
デフォルト状態では、優先度低のLEDの光り方をさせておいて、ボタンが押されると、ボタンに応じて優先度中の光り方や高の光り方で割り込むような形でLEDを光らせます。
優先度中や高の光り方が終わったら、デフォルトの優先度低の光り方に戻ります。
こういう処理をやりたかったのですが、優先度の処理をどうプログラミングするかについて少し悩んでおりました。
結局は、3つのタスクを用意して、優先度低のタスクがいつも動いており、もし優先度中や高のボタンが押されたら、それに該当するタスクが動くような処理をしました。
最終的には3つのタスクの内優先度が最も高い処理結果をLEDに引き渡すような作りにしました。
結果としては問題なく動いているのですが、大学の授業や社会人になってから学んだ本などでは、個人的にはですが、こういった処理の王道的なアルゴリズムといいますか、プログラミングの方法を見かけたことがありません。
なので、こういった優先度の処理に関する定番の方法や、もしくは、参考になる本などがありましたら、ご教示頂きたく質問させて頂いた次第です。
どうぞよろしくお願い致します。
  • 気になる質問をクリップする

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 3

checkベストアンサー

0

ご意見を拝見しました。

順序が前後しますが・・・

ここで、一番気になっていることとしては、こういった実装についても
言及している書籍などがあるかどうか、こういった処理の王道的な
アルゴリズムがあるかどうか?、という点です。

無いでしょうね。
ご要求の内容自体は、扱う範囲が小さすぎます。どちらかというと”小手先の実装方法”に過ぎないと思います。
アルゴリズムとかフレームワークといったような共通の考え方があるようには思えないです。

タイトルを「優先度の管理について」としましたが、ご意見を拝見したり
回答を書いている内に、単に優先度の管理の問題、というわけではない
気がしてきました。

優先度云々の話ではなくて、単に「LEDの点灯パターンの切り替えタイミング」じゃないですかね。
「いかなるタイミングでも優先度の高い方の点滅のさせ方をしたい!」というのであれば、また別の話になりますし。

この際に、できれば、状態Cの時の光り方を、最初からやり直すのではなくて、
状態Cが裏で動き続けていたような光り方から再開したいと思っておりました。

例示された例では、最小の単位時間が1秒ですから、タスク内で1秒毎に状態A/B/Cのそれぞれの状態についてON/OFFのどちらになるべきかを更新&保持しておいて(=点灯させたとしたら、いまON/OFFのどちらになるべきかを常に管理しておいて)、実際のLEDの点灯は状態A/B/Cのどれかに応じて現在のON/OFF状態を反映させる、という方法でいかがでしょうか。
あるいは、システムtickカウントを割り算でもすれば、状態A/B/Cそれぞれについて一意に現在のON/OFF状態が計算できそうでもあります。

状態Aの時に、優先度中のボタンが押されたら、状態Bには移りませんが、
状態AでのLEDの光り方が終わったら、状態Bには遷移したいです。

先に示した動作とは矛盾する部分が出てきそうですが、こちらのご要求にピッタリ合わせるなら、つぎのようになろうかと思います。

まず「状態AでのLEDの光り方が終わったら」とありますが、"始まり”と”終わり”を定義しないといけませんね。
おそらくは[ON→OFF]までが始まり~終わりの一連の動作になるのでしょうから、全体としては、

 for(;;) {
    on_off_time = 点滅周期判定
    LED点灯
    on_off_time秒待ち
    LED消灯
    on_off_time秒待ち
 }

くらいで十分ではないですか?
これなら、どんなタイミングで状態A/B/Cが変わっても、変なところでLEDの点灯パターンが急に変わることはないと思います。
ただ、状態Cの長い周期の点滅期間に、状態Aが2秒発生し、その後すぐに状態Cに戻ったという場合は状態Aはなかったような点滅になってしまいます。そういうケースにどうなるべきか?については、別途方針を決めないといけませんね。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2015/03/06 18:53

    ご回答ありがとうございます。
    大変参考になりました。

    確かに仰るとおり、細かい実装テクニックになるかと思います。
    こういうレベルだと、基本的に自分がやりやすい方法で実装すれば
    十分なのだと思います。
    ご意見ありがとうございました。

    また、2つの実装方針についても大変参考になりました。
    私が実装したのは、前者に近い形になるかと思いますが、
    後者のご意見についても参考にさせて頂きます。

    また、確かに仰るとおり、記述されたような実装で十分な気が致します。
    まだ理解できていない部分も多少ありますが、まずはご意見を拝見しながら
    再度実装方法について考えてみたいと思います。

    ご教示ありがとうございました。

    キャンセル

0

単純な処理だけに、"こうするべき"的な王道は無いように思います。
ですので、以下は「私だったらこうする(方法もある)」という程度に聞き流してください。

LEDの数は1つだけですよね?それなのに、タスクを3つも用意するというのは、ちょっとリソースがもったいないような気がします。

考え方をシンプルにして、「LEDを点滅させるタスク」を1つ用意するということで良いのではないでしょうか?つまり、そのタスクは「LEDを点滅させる」ことに特化したものということです。

そのタスクに対して、「点滅周期を速くしろ(遅くしろ)」というメッセージを送って、そのタスクに点滅間隔を変えさせればよいのではないでしょうか。
私なら、点滅周期を変えるくらいなら、メッセージ送信のような方法を取らず、単純に変数書き換え(=タスクはその変数を参照して点滅周期を決めている)くらいで済ましてしまうと思います。

参考になれば幸いです。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2015/03/06 11:25

    大変参考になりました。
    ご回答ありがとうございました。
    確かにタスクは1つにした方が、リソースの節約になるかと思います。

    ところで、お伺いしたいのですが、優先度の処理については、
    いかがでしょうか?

    タスクを1つにして、その中で優先度を管理しないといけないかと思いますが、
    優先度の管理について、もしお勧めの方法など何かありましたら
    ご教示頂けると大変助かります。

    以前試した方法としては、優先度毎にリクエスト保存用のキューを用意しておいて、
    for文で、リクエストが入っているキューについて、優先度の分(最大高中低の3つ)を
    回して処理をしておりました。
    ここで処理された結果の中から、一番優先度の高い処理結果を、LEDに反映させておりました。
    # こうしておくことで、LEDが優先度の高い光り方をした後に、自動的に、デフォルトの
    # 優先度の低い光り方に戻れるので。しかも、戻った際に、優先度の低い処理パターンが裏で
    # ずっと動いているような見え方になるかと思います。

    気になる点としては、優先度の管理は、プログラムとしては比較的良く行う類だと
    思いますが、これといった王道的な方法が紹介されてある文献を見かけたことがないことです。

    仰るとおり、比較的単純な処理にはなるかと思いますので、本などで
    紹介されるほどの内容ではない(誰でもすぐに作れるレベル)ということ
    なのかもしれませんが、意外と悩みながら実装した経緯があるので、
    皆様のご意見をお伺いしたいと思った次第です。

    お手数をおかけいたしますがよろしくお願い致します。

    キャンセル

0

すみません、質問の骨子を読み違えていたようです。
「タスク」「優先度」から、タスクの使い方の話かなーと。

「優先度」は、LEDの点灯パターンに対する優先度ですね。

システム全体の要求仕様が分からないので何とも言えないのですが、そもそもLEDの点灯パターン優先度のために「キュー」を用意する必要はありますか?ご質問からは、そこが読み取れないです。

システムがある状態AにあるからLEDを速く点滅させ、システムが別の状態Bにあるからゆっくり点滅でよい、そういう考え方ではないですか?
あるいは、「緊急事態」みたいな状態を表すフラグがあってその状態のときはLEDを速く点滅させ、
そうでないときはゆっくり点滅でよいとか。
いずれにしても、これらの場合ではキューは必要ないと思います。

要は、システムの中で何かの「状態」が変化したときに、その時の状態を(総合的に)判断して、LEDに対して「速く点滅しろ」「遅く点滅しろ」と指示するのが普通のように思えます。その緊急状態が解消したら、また判断を下してLEDタスクに指示を出す、そういう感じです。

とにかく、要求仕様がわからないので何とも言えません。貴方のいう「優先度」って、何で決まるのでしょうか?最初のほうで「ボタンが押されたら・・・」とありましたけど、ボタンが押されたらLEDが速く(遅く)点滅するというのは結果的にそうなるだけであって、ボタンが押されたらシステム内の「何か」が変化して、その結果としてLEDの点滅パターンが変わるんですよね?

ご質問の内容だけではキューが必要かどうかは判断できないです。ここでいう優先度は、ただの条件判断のような気がします。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2015/03/06 13:50

    ご回答ありがとうございます。
    大変勉強になります。

    キューが必要かどうかという点ですが、これは、今回の場合は、結局必須ではありませんでした。
    当初は、例えば優先度の高いボタンを連続して何回も押した場合に、優先度高のリクエストを
    優先度高用のキューに溜めておくべきかと考えていたのですが、
    リクエストを溜めておくと、ボタンを連打した際にずっと光り続けるように
    なるので、結局、リクエストは1つしか受け付けないようにしました。
    なので、キューは、必須とは言えないです。
    単なる変数でも良かったかと思います。

    ところで、状態遷移を使えば良いのではないか?、というご意見に
    なるかと思います。

    状態遷移を使った場合について考えたのですが、
    優先度高:状態A
    優先度中:状態B
    優先度低:状態C
    として考えた場合、デフォルトの状態だと、状態Cにあると思います。

    状態Cで、仮に
    on 5sec
    off 5sec
    という光らせ方をループさせていたとします。

    ここで、優先度高のボタンが押されてて、状態Aに切り替わったとします。
    状態Aの光り方が
    on 1sec
    off 1sec
    on 1sec
    off 1sec
    としたとします。

    この場合、状態Aの光り方が4secで終わるので、その後、もとの状態Cに戻って欲しいです。
    この際に、できれば、状態Cの時の光り方を、最初からやり直すのではなくて、
    状態Cが裏で動き続けていたような光り方から再開したいと思っておりました。

    その方が、優先度高の光か方が、割り込んで処理されたように見えて
    より自然な見え方になると思いますので。

    また、優先度Bの光り方が
    on 2sec
    off 2sec
    on 2sec
    off 2sec
    だとします。

    状態Aの時に、優先度中のボタンが押されたら、状態Bには移りませんが、
    状態AでのLEDの光り方が終わったら、状態Bには遷移したいです。
    なぜなら、状態Bの光る時間の方が長いので。

    説明が分かりにくくて申し訳ございませんが、概ねこのような処理を考えておりました。

    ここで、一番気になっていることとしては、こういった実装についても
    言及している書籍などがあるかどうか、こういった処理の王道的な
    アルゴリズムがあるかどうか?、という点です。

    タイトルを「優先度の管理について」としましたが、ご意見を拝見したり
    回答を書いている内に、単に優先度の管理の問題、というわけではない
    気がしてきました。

    また、こういった基本レベルは自分で考えるべき、といった話しにもなりそう
    ですが、そういう結論でも構いませんので、皆様のご意見をお伺いしたく
    質問させて頂いた次第です。

    お手数をおかけいたしますがよろしくお願い致します。

    キャンセル

関連した質問

  • 解決済

    LEDを光らせたい場合のInput, Outputについて

    お世話になっております。 現在Edisonを購入し、Node.jsでLEDを光らせるテストをしています。 初めての電子工作になります。 開発環境は Intel XDK IoT E

  • 解決済

    MS-Accessの一連の操作の簡略化

    Access 2016を使用しています。 Accessでの以下の操作の簡略化を求められています。 1.「外部データ」タブを選択する。 2.「保存済みのエクスポート操作

  • 解決済

    Arduino の pinmode() について

    前提・実現したいこと Arduinoの勉強を始めました.本のサンプルなどを動かしています. pinmode()の存在意義について疑問があります. 発生している問題・エラー

  • 受付中

    Lチカ GPIOを使って

    GPIOの割り込みでLチカをしたいです。 使用するマイコンは、以下のものです。 http://akizukidenshi.com/catalog/g/gM-06262/ ど

  • 解決済

    AtmelStudioを使ってC言語のLチカ用コードエラー

    前提・実現したいこと AtmelStudioを使ってC言語のLチカ用コードを書いています。マイコンは「ATMEL21E16B」を使用しています。以下、コード作成の参考にしているサイ

  • 解決済

    dsPIC30F2012の発振について

    dsPIC30F2012でタイマー割り込みを使用して、時間を制御するように検討しているのですが、 コンフィグでXT_PLL16とかFRC_PLL8とかのPLLを使用した設定では、T

  • 解決済

    UIBarButtonItem の style: で .done と .plain の違いはなんで...

    すみません、かなりしょぼい質問かもしれません。 UIBarButtonItem を実装する過程で 例 let doneButton = UIBarButtonItem(ti

  • 受付中

    スマホのライトを点滅させるには

     前提・実現したいこと Android Studioを使ってスマホのライトを点滅させたいのですが、方法がわかりません。 どのようにすればいいのでしょうか?

同じタグがついた質問を見る

  • C++

    3581questions

    C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。