福嶋です。

Miyaki Masahiro <miyaki / wni.co.jp> wrote:
> ruby-gtkを使っていてThreadの中でsocketのgetsやreadlineを
> やると妙に時間が掛かるのですが、どうしてなんでしょうか。

ruby-gtk の中で、Ruby側のThreadのスケジューリングが100ms毎にしか
呼ばれないようになっているからだと思います。

確か、gtk_idle_add()を使うと頻繁にスケジューリングが起こって、そ
れ自体がCPUを消費してしまうので、代わりに gtk_timeout_add() を使
うようになったんだったと思います。

gtk_idle_add()を使うように戻して、その代わり、idle()の中で
rb_thread_schedule() ではなく rb_thread_wait_for() を呼ぶようにし
てみました。これで大体 O.K. だと思います。



diff -ru gtk-0.21.orig/src/rbgtk.c gtk-0.21/src/rbgtk.c --- gtk-0.21.orig/src/rbgtk.c Tue Aug 10 16:10:09 1999 +++ gtk-0.21/src/rbgtk.c Fri Sep 10 18:47:23 1999 @@ -1,4 +1,7 @@ #include "global.h" +#ifdef HAVE_SYS_TIME_H +# include <sys/time.h> +#endif VALUE gtk_object_list; VALUE mGtk; @@ -2183,8 +2186,14 @@ static gint idle() { + struct timeval wait; + + wait.tv_sec = 0; + wait.tv_usec = 100000; /* 100ms */ + CHECK_INTS; - if (!rb_thread_critical) rb_thread_schedule(); + if (!rb_thread_critical) rb_thread_wait_for(wait); + return Qtrue; } @@ -2295,7 +2304,7 @@ Init_gtk_requisiton(); Init_gtk_allocation(); -#if 0 +#if 1 gtk_idle_add((GtkFunction)idle, 0); #else /* use timeout to avoid busy wait */
これだと、いったん Ruby 側のスケジューリングに入ってしまうと、し ばらくは gtk 側に制御が戻りません。まあ GUI ですし、100ms くらい なら実質問題は無いはずですが。 そもそも根本の問題はruby側とgtk側の両方で同時にI/O待ちが起こる可 能性があることだと思います。一つの select にまとめられれば解決す るんじゃないかと思いますが、それは現状では無理っぽいですね。 --- 福嶋正機