アプリ版:「スタンプのみでお礼する」機能のリリースについて

やりたいことは、tail -fのようにファイルに追加があれば、検知して読み出したいのですが、条件として、selectを使う必要があります。
具体的に下記処理をしています。
1.ファイルを読み込み専用でopen
2.1のディスクリプタをreadfdsに設定してselectで数秒待ち
3.2でreadfdsにディスクリプタがセットされていたらすべて読込

しかし、ファイルに追記されていないにも関わらず
2の待ちが終わり、3で0バイトの情報を読む形になります。
ディスクリプタに標準入力の0を指定するとうまく待ちとなります。

ネットで検索をしたのですが、あまりそのような処理は載っておらず
tailのソースでもselectは利用していないため、困っております。
どのようにすれば、よいのでしょう。

ソースは、まだ独自ライブラリを利用している部分があるため
一般公開できるレベルに落とし込んでおりません。申し訳ないです。
専門の方ならおそらく処理を見て、理解できると思い、記載は不要と判断しました。

A 回答 (2件)

私もlinux(centos6.3)で確認しましたが、同様の現象でした。


マニュアルを参照すると、(以下抜粋)
---------------------------------
select() や pselect() を使うと、プログラムで複数のファイルディスクリプターを監視し、 一つ以上のファイルディスクリプターがある種の I/O 操作の 「ready (準備ができた)」状態 (例えば、読み込み可能になった状態) になるまで待つことができる。 ファイルディスクリプターが ready (準備ができた) とは、 (read(2) などの) 対応する I/O 操作が停止 (block) なしに実行したり、 十分小さな write(2) を実行したりできる状態にあることを意味する。
-------------------------------------
これは、読込に関して言えば、ブロックされないで読み込める状態なら、select完了というように読み取れます。標準入力からの読込については、たしかに、データが無いときはブロックされるので、
selectで待つ意味がありますが、ファイルの読込については、ブロックされないので、selectで待っても、即座にselectが完了してしまいます。(たぶんこれがselectの仕様かと思いますが)
ですので、対策としては、「一定時間(10ミリ秒~1秒程度)スリープして、ファイルを読み込み、データがあれば表示する」というのを繰り返すというのが、現実的な方法かと思います。
tail -f相当の機能ということであれば、それで十分かと思います。
以下、参考URLです。
http://linuxjm.sourceforge.jp/html/LDP_man-pages …
    • good
    • 0
この回答へのお礼

ご回答有難う御座います。
自分も同様の仕様認識です。
しかし、selectのような関数が、まさかこんなこともできないのか?
という疑問もありまして、方法があればと思い、相談した次第です。
最終手段としてポーリングは検討していますが、できればイベントドリブンにするのが
美しいと考えています。

お礼日時:2015/03/06 10:12

使ったことはないので本当にできるかはわかりませんが、


inotifyのIN_MODIFYイベントをキャッチすればリアルタイムな変更にも対応できそうです。

といいつつ、こういったイベントキャッチ系のシステムコールといえども、
その裏側は定期的な割り込みのタイミングでしか見ていないので、
程度の差こそあれ、#1の方のご回答のような自前コードでも本質的には変わらないような気がします。
つまり、リアルタイムな変更に対応したような気分に浸るか、
なんちゃってだけど体感的にはリアルタイムに対応するプログラムを自作したという満足感に浸るか、程度の違いでしょう。

ちなみに、0は、多分パイプだから、selectでキャッチできるのでしょう。
fork→execするとき、forkの前にpipe作るでしょ、その原理だと思います。
    • good
    • 0
この回答へのお礼

ありがとうございます。
やはり、ポーリングするしかなさそうですね。

お礼日時:2015/03/09 10:10

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