2013年1月
- あけました
01/01
stdinから与えられた文字列をひたすらウィンドウに表示するツール1が欲しくなったので作ろうとしている(xcbで書いてる)が、Xのイベントを捌きつつstdinからの入力を処理する必要がある。しばらく前からいくつかの方法を試しているが中々上手く行かない。
stdin(0番)とXのfd(xcb_get_file_descriptor()で取れる)をselectする
これが一番真っ当な方法に思えるが、やってみるとイベントを適切なタイミングで拾えない(MapNotify直後のExposeとか、DestroyNotifyとか)
xevやxmonなどのツールで確認したところ、サーバからイベントは届いている(が、上手く取得できていない)
イベントをポーリング(xcb_poll_for_event)して、イベントが来てないときは標準入力を読む
WindowsでよくあるPeekMessageを使う方法と同じ発想。Unix的ではない?
普通にやるとreadがブロックしてイベントを拾えなくなるので、待ち時間0でselectする
- このままだと全力で回り続けるのでCPUを100%食う
sched_yieldで残りタイムスライスを放棄できるらしい(Windows APIで言うところのSleep(0))。これを使ってみたが、依然としてそれなりに(手元のマシンで5%ほど)CPUを食う
- もっと長くスリープすればCPU使用率は下がるだろうが、イベント処理が遅れる可能性がある
- イベントを取りこぼす問題は起こらない
まだ試していないのはマルチスレッド化(Xイベント処理/入力処理の2スレッド)だがあまりやりたくない。最初の方法でイベントを上手く拾えない原因を突き止めたいところ。
- もしかして: イベントキューに入ってる
イベントがソケットのバッファから読み出されてXCBのイベントキューに入ってしまえば、selectでは検知不能
- とするとポーリングするしかないのか?
時計とかバッテリ残量を表示したい。xtermで良くないか、という説がある(実際今はそうしている)が、端末は入力フォーカスを受け取ってしまうので何かの拍子にフォーカスが入ってしまいがちなのが難点 (1)