[#954] Rational — keiju@... (Keiju ISHITSUKA)

けいじゅ@SHLジャパンです.

23 messages 1996/10/30
[#955] Re: Rational — matz@... (Yukihiro Matsumoto) 1996/10/30

まつもと ゆきひろです.

[#968] Re: Rational 1996/10/31

けいじゅ@SHLジャパンです.

[ruby-list:765] Re: httpd.rb (Re: sample/svr.rb (socket, select))

From: matz@... (Yukihiro Matsumoto)
Date: 1996-10-07 01:52:51 UTC
List: ruby-list #765
In message "[ruby-list:760] httpd.rb (Re: sample/svr.rb (socket, select))"
    on 96/10/05, Hara Shin-ichiro <sinara@blade.nagaokaut.ac.jp> writes:
|原です。

|奇遇ですねー。私も朝から Thread の練習にと思って、同じことをしてい
|ました。私の考えた方法は、そのまんま svr.rb をぱくって
|
|def session(s)
|# s でなんとか
|  s.close
|  $m.syncronize{ $threads -= 1 }
|end
|while TRUE
|  nsock = select(socks)
|  next if nsock == nil
|  for s in nsock[0]
|    if s == gs
|      ns = s. accept
|      socks.push(ns)
|    else
|      socks.delete(s)
|      while $threads >= $max_thread; sleep 0.1; end;
|      $m.syncronize{ $threads += 1 }
|      Thread.start{ session(s) }
|    end
|  end
|end
|
|と、いう風にしてみました。これでいいのかなー。

threadを活用してsvr.rbをかくなら以下のようになるでしょう。

# socket example - server side using thread
# usage: ruby tsvr.rb

require "socket"
require "thread"

gs = TCPserver.open(0)
addr = gs.addr
addr.shift
printf("server is on %d\n", addr.join(":"))

while TRUE
  ns = gs.accept
  print(ns, " is accepted\n")
  Thread.start do
    s =	ns			# save to dynamic variable
    while s.gets
      s.write($_)
    end
    print(s, " is gone\n")
    s.close
  end
end

短いですね。でもこれを書いてみたら,Socket#acceptがthread対
応になっていませんでした。次のリリース以降でしか動きませんね。

|で、結論として Thread を使わないほうが倍も早いです。^^; Thread
|の実装にファンクションコールの select を使っているそうなので、
|どっちにしろ select を使っている事になり、Thread のご利益が少
|ないのかもしれません。server の CPU が速くて、コネクションあた
|りの通信速度が遅く、送るデータサイズが大きければ結果はちがうと
|おもいますが。

原さんのsvr.rbが何をしているのか良く分からなかったのですが
(特にsyncronizeのあたり),threadに関して一般的に言えるのは

  * threadを使うことによって処理全体が高速化されることは絶対
    にない

ということです。特にrubyのthreadは毎回スタックをコピーしてい
ますので,あまり軽くないですから。じゃあthreadを使うメリット
はないのかというと,ブロックすることがなくなるのでインタラク
ティヴなプログラムの反応時間が速くなることが期待できることで
しょう。

|sleep 0.1 をやめると、さらに極端にパフォーマンスが落ちます。普
|通、各スレッドの働き具合をコントロールするにはどうするのでしょ
|うか?

自分から実行権を渡すためにはThread.passを使うと思います。
sleepしちゃうと寝てしまいますから。

                                まつもと ゆきひろ /:|)

In This Thread

Prev Next