
No.6ベストアンサー
- 回答日時:
>キューを受け取って溜まっているときは処理を行うし、
>溜まっていなければ処理をしないようなプログラムは可能でしょうか?
同期キューの Queu モジュールで出来ますよ。
Queuのgetメソッドはキューが空なら処理をブロック出来ます。
No.9
- 回答日時:
大元の質問は下記でよいでしょうか。
https://oshiete.goo.ne.jp/qa/11497059.html
こちらの方にも回答しましたが、Websocketを使うということなら受信待ちはwebsocketパッケージの中でやってくれるので自前で無限ループを書く必要はなく、各種イベントハンドラを登録してイベントループを行う関数(run_forever)を呼び出すだけです。イベントが発生したら該当のイベントハンドラが呼び出されるのでイベントハンドラに処理を記述します。
イベントループの止め方はパッケージのマニュアルを確認ください。基本的にはイベントハンドラの中で何か関数を呼び出すか、イベントハンドラの返値でループを止めさせます。
自前でイベントループを書くという話になると、while無限ループは基本です。ただしループを全力で廻すとCPUを浪費するので、イベント発生を待つ処理(システムコール)を呼び出してイベント発生まで待つようにします。
イベントループの基本的なフローは以下のようになります。
while True:
イベント発生待ち(listen, recv, selectなど)
イベント識別と処理
if 終了判定:
break
終了処理
重要なのはイベントループで待てるのが一か所だということです。
例えばTCP/IPサーバでソケット接続待ちとデータ受信待ちをそれぞれ別の待ちにしてしまうと、接続待ちのときにはデータを受信できず、受信待ちしていると新しい接続がきても繋げません。
これを解決する一つの方法がselectです。selectは複数のイベント待ちを同時に管理し、いずれかのイベントが発生すると返ってきます。返値から発生したイベントを識別して処理します。
他の解決策としてはマルチスレッドにして各スレッドでは一つのイベントだけ待てばよいようにするという方法もあります。
No.8
- 回答日時:
> selectモジュールについて、ちょっと調べたところ、ポーリングをして一定時間間隔で調べに行っているらしいのですが、
違います。
OSからのイベント通知を待っているだけですので、待っている間はCPUを使いません。
キーボード入力待ちと同じです。
> ソケット通信のlistenで待つなど
listenだと、1つのソケットしか監視できませんが、selectだと複数のソケットやキーボード、パイプなどからの入力を待てます。
selectが待つのは入力だけではないですが、説明を簡単にするために、入力を待つ話だけ書きます。
ケース1.selectをコールした時点で、引数で指定した入力(広義のファイル(ファイル、ソケット、端末、パイプ等))にデータがたまっていれば、どの入力にデータがたまっているの(複数かも)か、返します。
ケース2.コールした時点でたまっていなければ、どこかの入力が来るまで待って、どこに入力があったかを返します。
ケース3.指定時間待ってもどこからも入力が無ければ、タイムアウトしたら空(何も入力が無かった)を返します。どこかの入力があるまで無限に待つこともできます。
例えば、相手とつながったTCPセッションと、端末の両方を待って、端末から入力があればTCPで相手に送り、TCPから入力があれば端末に表示するとかで使えます。
r, w, x = select.select([sys.stdin, socket],[],[])
for inp in r:
if inp == sys.stdin:
端末入力があった場合の処理(ソケットに書くとか)
if inp == socket:
TCPソケットから入力があった場合の処理(sys.stdoutに書くとか)
No.7
- 回答日時:
No.5
- 回答日時:
scanfは入力待ちなので、Pythonなら input()でいいですよね?
デーモンは、普通はマルチプロセスかマルチスレッドで、
1スレッドが入力を待ち続けるか、あるいは、時々データが来ているかチェックするかですね。
https://docs.python.org/ja/3/library/select.html
を使うと、
「指定した複数の入力ストリームの1つ以上に入力データがあるか、あるいは、指定時間経つまで待つ」
という処理ができます。
No.4
- 回答日時:
>>そもそも、そのデータがキューに溜まったことを検知して割り込み処理させるために、
while無限ループが必要なのではないでしょうか?
受信処理ではありませんが、C#のタイマー処理のサンプルとして以下のようなコードがあります。
以下のコードでは、200ms毎にtimer1_Tickが呼び出されて処理が実行されます。
でも、そのtimer1_Tickを呼び出す処理はユーザが記述する必要はありません。
こういうのは、コールバック関数といわれていて、規定の時間が来ると、InitializeComponentでtimer1_Tickが登録してあるので、勝手に呼び出されるのですね。
つまりは、whileループが無くても、割込処理でtimer1_Tickが処理されます。
そのタイマー割り込みのような感じで受信データが来たら、例えば「DataReady」って名前の関数を登録しておけばいいわけです。
ま、縁の下の力持ちルーチンとして、EventHandlerが活躍してくれているのでしょうけどね。
// デザイナーのコード
private void InitializeComponent()
{
this.timer1 = new System.Windows.Forms.Timer();
this.timer1.Enabled = true;
this.timer1.Interval = 200;
this.timer1.Tick += new System.EventHandler(this.timer1_Tick);
}
private System.Windows.Forms.Timer timer1;
// ユーザーコード
private void timer1_Tick(object sender, EventArgs e)
{
// タイマーでやらせたいことを以下に記述:
//
}
なお、余談ですが、C#では、不定期に来るネットからの受信データなどの処理をGUIに影響でないように処理するために、スレッドをうまく活用して非同期処理ができる構文が用意されていたりします。
>>c言語やアセンブリならば、
データがキューに溜まったことを検知できるのでしょうか?
まあ、検知できるのでしょうか?というよりも、検知できるようなプログラムを自分で書くか、あるいは、だれかにライブラリーとして用意してもらうってことだと思います。
昔のことですが、自分ではそういったコードが書けないため、知人のベテラン・プログラマさんがアセンブラで送受信用のドライバーコードを書いてくださいました。
送受信用のLSIのレジスタをビットレベルで制御されていました。
No.3
- 回答日時:
まずは、OS側でそういう機能が提供されているか?が問われる気がします。
提供されていれば、Python側で、その機能を利用できるようなライブラリ等を使うとか、無ければ、ライブラリを自分で作るってことになると思います。
たとえば、データ受信処理で、受信データがキューにたまり、それをPythonで処理したいとします。
whileループなら、sleepを入れて定期的にキューにデータがたまっているか?をチェックする処理になりますよね?
でも、そういうのではなく、キューにデータが入ったら、受信データ処理ルーチンが呼ばれるようにしたいとなれば、データがキューにたまれば、受信データ処理ルーチンが呼び出されるような割り込み処理(トリガー処理)になると思います。
C言語やアセンブラであれば、処理ルーチンのエントリアドレスなどを渡すことで、そういう割り込み処理が可能となった気がしますけど、Pythonは知らないので、どう書くのか残念ながらわかりません・・・。
No.2
- 回答日時:
まずトリガーを待って、トリガーを受け取るごとに処理をして、次のトリガーを待つという無限ループ処理を自作するならwhile無限ループはほぼ必須ですね。
forで誤魔化すこともできなくはないけど本質的ではない。あとはトリガーをどう待ってどう受け取るかです。socketでTCP/IPセッションの接続をlistenで待つとか、データ受信をrecvで待つとかだったらsleepは必要ないですね。
なお、GUIをtkinterとかで書くのだとイベントハンドラを定義してメインループを呼び出すと無限ループとかイベント待ちは中でやってくれるので自分で書く必要はないです。ボタンを押すなどのイベントが発生したら対応するイベントハンドラが呼ばれます。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- その他(プログラミング・Web制作) uwscとWinShotを使いスクリーンショットを撮る 1 2022/06/30 21:15
- Visual Basic(VBA) 【VBA】印刷マクロのループ処理が反映されません 3 2022/08/09 02:15
- Ruby プログラミング 3 2023/06/09 14:30
- Visual Basic(VBA) VBAのユーザーフォームのテキストボックスに入力制限をしたい 6 2022/11/15 08:28
- Java Java 南京錠 2 2023/02/04 11:46
- C言語・C++・C# C 言語の Gauss Jordan 法について 2 2022/12/28 11:16
- C言語・C++・C# 宣言する関数の形が決まっている状態で、 str1とstr2の文字列をこの順に引っ付けてstrに保存し 2 2022/05/30 18:21
- JavaScript カラーミーショップのsectionループ内で、[引数][戻り値]ありの関数的な処理を行いたいです。 1 2022/05/07 19:39
- C言語・C++・C# numpyスライス機能を使った数値計算 2 2023/05/08 16:01
- Java Javaの問題なのですが、 永久ループを使って以下に従って数値を出力するプログラムを作成する。 ・1 3 2023/06/06 18:43
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
お家デートをしててハグを長い...
-
内部処理形式ってなんですか
-
エクセルで、日付を入力すると...
-
英語の知識があって、数学の知...
-
皆さんが1番信じているものはな...
-
「ご処理進めて頂きますようお...
-
VBA Progress barが動作しない
-
カスタムドロー
-
VBAでCOPYを繰り返すと、処理が...
-
計算の問題なのですが、 例えば...
-
VBAでループ内で使う変数名を可...
-
インタラクティブの反対語は?
-
ハードウェア処理とソフトウェ...
-
VCで処理中ダイアログボックス...
-
文字が入力されたときに処理に...
-
シェルアイコンがイメージリス...
-
パワーポイントでは、どうすれ...
-
掃き出し法 コツ
-
VBの質問#if 0 then ってどう...
-
マルチプロセッシングとマルチ...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
「ご処理進めて頂きますようお...
-
エクセルで、日付を入力すると...
-
VBAでループ内で使う変数名を可...
-
【Excel】特定の文字を含むセル...
-
switch の範囲指定
-
EXCEL VBA マクロ 実行する度に...
-
UMLでの例外処理
-
DoEventsがやはり分からない
-
月度は何て読みますか?
-
お家デートをしててハグを長い...
-
VB.NET Excelを読み込んでDataT...
-
VBの質問#if 0 then ってどう...
-
Do~Loopした回数をカウントしたい
-
VBAでCOPYを繰り返すと、処理が...
-
メルカリのメルカードで買い物...
-
インタラクティブの反対語は?
-
Loadイベント中にほかのイベン...
-
リョウ・・・量?料?
-
vba 空のデータをSplitする時の...
-
findは動くがfindnextがマクロ...
おすすめ情報
ラズパイのRaspbianです!
専門知識ありがとうございます!
v4l2さんに質問なんですが、
「データがキューにたまれば、受信データ処理ルーチンが呼び出されるような割り込み処理(トリガー処理)」
について、
そもそも、そのデータがキューに溜まったことを検知して割り込み処理させるために、
while無限ループが必要なのではないでしょうか?
c言語やアセンブリならば、
データがキューに溜まったことを検知できるのでしょうか?
返答ありがとうございます!
selectモジュールについて、ちょっと調べたところ、
ポーリングをして一定時間間隔で調べに行っているらしいのですが、
これはwhile無限ループとは違うのでしょうか
そもそもわたしの解釈が間違いでしょうか?
scanf、input、のようなcpu負荷をかけないような待ち方をしたいのですが、
複数プロセスからのキューを待ち受けるような
イベント駆動のプログラムを書きたい時には
GUIの何かしらの機能を使う、ソケット通信のlistenで待つなど、をしなければならないのでしょうか
返信ありがとうございます!
multiprocessingの Queueの
get()はちゃんとブロックするようになっているんですね。
今までempty()でいちいちチェックしていました。
ありがとうございます!
試したところcpu負荷も低いままになりました!
selectを初めて知りました!
使い方は書いてくださったコードでだいたい分かりました。
マシンに関するあらゆる入力などを待てるのですね。
また、cpuを使わずに、osからのイベントを待てるのですね!ありがとうございます!
限界の、一定時間待つ、というタイムアウト時間だったのですね!
ウェブソケットは、cpu負荷をかけずにosからのイベント、システムコールを待っていてくれてると分かりました!
それがいろんな種類の時、
スレッドやプロセスでそれぞれ待つ、や、selectを使えば良いのですね。
ありがとうございます!