重要なお知らせ

「教えて! goo」は2025年9月17日(水)をもちまして、サービスを終了いたします。詳細はこちら>

電子書籍の厳選無料作品が豊富!

ラズパイで、ウェブから、ウェブソケットで、受信待ちするPythonプログラムを、ラズパイ起動時に自動実行したいのですが、処理量が多いのか、画面が真っ暗になったり、高熱になったりして、うまく動きません。
無限ループで受信していて、
受信していないときは常に回り続けます。
これが良くない場合、sleepを入れるしかないのでしょうか。
他に方法があれば教えてください

質問者からの補足コメント

  • うれしい

    lowrider_2005さん回答ありがとうございます。
     自動起動単体では成功したのを確認しています。
    Linuxで、rc.localにsudo python3 /○○/.../○○.py
    のようになっており、テキストファイルの数値を自動起動度に、カウントアップ書き換えさせました。
     現在、自分で上記の1文だけ書き換えて自動起動させているのは、以下の受信待ちプログラム1つだけです。
     Pythonプログラムで、
    while True:
     if 受信したら
      処理
    のようになっています。
     この受信待ちプログラムを動かすと、真っ暗な画面にマウスポインタだけある範囲内だけ動かせるような状態になります。

      補足日時:2020/02/21 18:48
  • 自動起動前に手動で受信待ちプログラムを実行するときは正常に動きました。
     手動で動かしてリソースモニター、topで確認、
    自動起動でsarで記録を録る、などを試してみたいと思います。
     これらの問題は仕方のないことなのでしょうか?
    受信待ちのプログラムはよく作られるものだと思うのですが、結局はsleepを入れて、受信ループの速度を遅らせるしかないのでしょうか?

      補足日時:2020/02/21 18:48
  • へこむわー

    すいません訂正がありました。
    sudo python3 ○○.py ではなく
    sudo python3 ○○.py &でした
    バックグラウンドで動かしています

      補足日時:2020/02/22 19:27
  • うーん・・・

    バックグラウンドで動かしたらプログラムが終了しなくとも、デスクトップ画面が出ても良さそうですが、黒い画面にマウスカーソルがあるだけで止まってしまいます。

      補足日時:2020/02/23 16:35
  • うれしい

    回答ありがとうございます!

    ラズパイは3Bです。

    受信までブロックする、か、タイムアウトでエラーを吐かせる、ようにするのですね!

    Pythonコード上でそれぞれどのように書くのでしょうか
    そのようなモジュールがあるのでしょうか
    タイムアウトでエラーを吐く場合は
    時刻を測り、ある時間間隔が経ったら、という条件分岐して、raiseで例外を発生させるのでしょうか?

      補足日時:2020/02/24 16:55
  • うれしい

    返信ありがとうございます!

    ウェブソケットが常時抜けて無限ループになっているのではなく、ブロックしてくれているのは分かっていたのですが、説明が複雑になると思い、正確に書いていませんでした。すみません!

    また、タイムアウトの設定ができるのを知りませんでした!

    Windowsの場合はタイムアウトつけることにより、
    キーブレイクできるようになるのですね!

    丁寧に答えていただきありがとうございます!!

      補足日時:2020/02/27 14:59
  • HAPPY

    そもそも無限ループで常時チェックするようなプログラムは良くないのは思っていたのですが、
    ソケット通信や、ウェブソケット、GUIなど、ある程度用意されたものしか、待っている間ブロック、というのができないと思っており、用意されてないものをやるときはsleepを入れるのしかないのか?と悩んでいました!
    しかし、 Queueのget()でブロック待ちできたり、
    selectモジュールなどがあることを知り、モヤモヤが解消しました!

    ありがとうございます!

      補足日時:2020/02/27 15:02

A 回答 (4件)

> Pythonコード上でそれぞれどのように書くのでしょうか


socketを使って自作するならrecvを呼び出せばデフォルトでは受信するまで待ちますけど。
あとタイムアウトはエラーを吐かせるのではなく、タイムアウト時間を設定しているとタイムアウトで例外が発生するので例外を拾ってエラーにならないように続きを実行するように書くのです。なぜならタイムアウトはキーブレイクなどを確実に受け取るためにOSから制御を戻すために設定しているのでタイムアウトが起こることは異常ではないからです。もしかするとLinux系だとソケットのタイムアウトを設定しなくてもキーブレイクを受け取れるかもしれませんが、少なくともWindows環境ではソケットを待っている間はキーブレイクも受け取ってくれないので、タイムアウト設定はそれに対する対策ですね。キーブレイクさせる必要がなければタイムアウトなしの方が簡単でしょう。

ただWebsocketのパッケージを使うというなら、上記のような記述は不要と思います。適当なイベントハンドラを設定してrun_foreverを呼び出せばイベントループ処理はライブラリ内でやってくれるので無限ループを自作する必要はないです。(下記サイト参照)
なお下記サイトの長く保つクライアント例ではon_openハンドラで色々と書いていますが、クライアントがサーバーからのメッセージを受けて作業をするならon_messageハンドラの方に実作業の記述をすることになるでしょう。

PythonでWebSocketのお勉強
https://make-muda.net/2017/10/5645/
    • good
    • 1

> while True:


>  if 受信したら
>   処理
この構造自体は問題ありませんけど『受信したら』の部分がOSコールで受信まで待つのでなく待ちなしのチェック&ループならCPU負荷が異常に高くなっているかもしれません。ラズパイって初代ですか?
ノンブロッキングコールになっているようなら受信までブロックするかせめて0.1秒以上のタイムアウトを設定して受信しないときのループを抑制しないと拙いですね。なおタイムアウトは例外になるので例外処理必須です。
    • good
    • 1

「無限ループしてるので rc.local が終わらない」というオチ?

    • good
    • 1

ラズパイかどうかは関係なくて、それはOSに依存する話ではないでしょうか。


Windows系ならサービスに登録して自動起動にすればいいし、Linux系ならrcでサービスを起動するとかいろいろです。
で、それをしておいても起動に失敗するなら、リソースモニターとかtopとかで監視しながら手動で起動してみて原因を探るとか、sarで記録を取っておいて確認するとかでしょうか。
まぁそれが面倒なら怪しいところにsleep入れながら試すとか、起動の順序を考え直してみるとかでしょうか。

スクリプトが無限ループしてるとかでは無いんですよね?
    • good
    • 1

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!