[#6219] Ruby連載 第4話 — matz@... (Yukihiro Matsumoto)

まつもと ゆきひろです

32 messages 1998/02/04
[#6221] Re: Ruby連載 第4話 — Shin-ichiro HARA <sinara@...> 1998/02/04

原です。

[#6224] Re: Ruby連載 第4話 — Yasunari Momoi <conan@...> 1998/02/04

ももちゃん@あるもにこすです.

[#6225] Re: Ruby連載 第4話 — matz@... (Yukihiro Matsumoto) 1998/02/04

まつもと ゆきひろです

[#6249] Re: i++ — 助田 雅紀 <masaki.suketa@...>

助田です。

33 messages 1998/02/04
[#6252] Re: i++ — gotoken@... (GOTO Kentaro) 1998/02/05

ことけんです

[#6255] Re: i++ — matz@... (Yukihiro Matsumoto) 1998/02/05

まつもと ゆきひろです

[#6260] Re: i++ — Yuji Shigehiro <sigehiro@...> 1998/02/05

しげひろです.

[#6314] RE: ruby's design policy (Re: I'd like to subscr ibe this ML) — 助田 雅紀 <masaki.suketa@...>

オブジェクト指向周辺をぶらぶらしている助田です。

11 messages 1998/02/06

[#6333] ruby 流に添削して下さい — nkon@...2.3web.ne.jp

13 messages 1998/02/07
[#6335] Re: ruby 流に添削して下さい — OZAWA Sakuro <crouton@...> 1998/02/07

さくです.

[#6372] ruby 1.1b7 released — matz@... (Yukihiro Matsumoto)

まつもと ゆきひろです

24 messages 1998/02/10
[#6402] parsedate (Re: ruby 1.1b7 released) — WATANABE Hirofumi <watanabe@...> 1998/02/13

わたなべです.

[#6405] Re: parsedate (Re: ruby 1.1b7 released) — Tadayoshi Funaba <tadf@...> 1998/02/13

ふなばです。

[#6407] Re: parsedate (Re: ruby 1.1b7 released) — matz@... (Yukihiro Matsumoto) 1998/02/13

まつもと ゆきひろです

[#6373] call for scripts — matz@... (Yukihiro Matsumoto)

まつもと ゆきひろです

133 messages 1998/02/10
[#6414] Re: call for scripts — Terutuoshi Kaneshiro <k-teru@...06.odn.ne.jp> 1998/02/14

金城です.

[#6428] Re: call for scripts — matz@... (Yukihiro Matsumoto) 1998/02/16

まつもと ゆきひろです

[#6448] Re: call for scripts — Terutuoshi Kaneshiro <k-teru@...06.odn.ne.jp> 1998/02/16

金城です.

[#6452] Re: call for scripts — matz@... (Yukihiro Matsumoto) 1998/02/17

まつもと ゆきひろです

[#6481] Re: call for scripts — Kikutani Makoto <kikutani@...> 1998/02/17

きくたに@ぷ〜たろ〜です。

[#6483] Re: call for scripts — OZAWA Sakuro <crouton@...> 1998/02/17

さくです.

[#6495] Re: call for scripts — WATANABE Hirofumi <watanabe@...> 1998/02/18

わたなべです.

[#6416] Re: call for scripts — shugo@... (Shugo Maeda) 1998/02/14

前田です。

[#6417] rgrep (Re: call for scripts) — shugo@... (Shugo Maeda) 1998/02/15

前田です。

[#6423] Re: rgrep (Re: call for scripts) — matz@... (Yukihiro Matsumoto) 1998/02/16

まつもと ゆきひろです

[#6612] Re: call for scripts — Tadayoshi Funaba <tadf@...> 1998/02/21

ふなばです。

[#6582] File::Separator on cygwin — OZAWA Sakuro <ozawa@...>

小澤さくです。

19 messages 1998/02/20
[#6583] Re: File::Separator on cygwin — WATANABE Hirofumi <watanabe@...> 1998/02/20

わたなべです.

[#6586] Re: File::Separator on cygwin — OZAWA Sakuro <ozawa@...> 1998/02/20

小澤さくです。

[#6591] ruby 1.1b8 released — matz@... (Yukihiro Matsumoto)

まつもと ゆきひろです

32 messages 1998/02/20
[#6620] rbc.rb and binding — shugo@... (Shugo Maeda) 1998/02/22

前田です。

[#6629] Re: rbc.rb and binding — keiju@... (石塚圭樹 ) 1998/02/23

けいじゅ@日本ラショナルソフトウェアです.

[#6643] Re: rbc.rb and binding — shugo@... (Shugo Maeda) 1998/02/23

前田です。

[#6649] Re: rbc.rb and binding — keiju@... (石塚圭樹 ) 1998/02/23

けいじゅ@日本ラショナルソフトウェアです.

[#6650] Re: rbc.rb and binding — matz@... (Yukihiro Matsumoto) 1998/02/23

まつもと ゆきひろです

[#6667] JRI 0.5 worked (was Re: rbc.rb and binding) — OZAWA Sakuro <crouton@...> 1998/02/23

さくです.

[#6687] Re: JRI 0.5 worked (was Re: rbc.rb and binding) — shugo@... (Shugo Maeda) 1998/02/24

前田です。

[#6712] JRI and JDBC — OZAWA Sakuro <ozawa@...> 1998/02/24

小澤さくです。

[#6635] hello — WATANABE Tetsuya <tetsu@...>

渡辺哲也と申します。

15 messages 1998/02/23

[#6706] Re: Counter class — toyofuku@...

豊福@パパイヤです。

12 messages 1998/02/24

[#6735] Mutex/ConditionVariable/Queue — shugo@... (Shugo Maeda)

前田です。

27 messages 1998/02/24
[#6746] Re: Mutex/ConditionVariable/Queue — keiju@... (石塚圭樹 ) 1998/02/25

けいじゅ@日本ラショナルソフトウェアです.

[#6747] Re: Mutex/ConditionVariable/Queue — shugo@... (Shugo Maeda) 1998/02/25

前田です。

[#6752] Re: Mutex/ConditionVariable/Queue — senda@... 1998/02/25

From: shugo@po.aianet.ne.jp (Shugo Maeda)

[#6754] Re: Mutex/ConditionVariable/Queue — shugo@... (Shugo Maeda) 1998/02/25

前田です。

[#6756] Re: Mutex/ConditionVariable/Queue — senda@... 1998/02/25

From: shugo@po.aianet.ne.jp (Shugo Maeda)

[#6786] Re: Mutex/ConditionVariable/Queue — senda@...

From: shugo@po.aianet.ne.jp (Shugo Maeda)

33 messages 1998/02/26
[#6791] Re: Mutex/ConditionVariable/Queue — shugo@... (Shugo Maeda) 1998/02/26

前田です。

[#6794] Re: Mutex/ConditionVariable/Queue — shugo@... (Shugo Maeda) 1998/02/26

前田です。

[#6796] Re: Mutex/ConditionVariable/Queue — keiju@... (石塚圭樹 ) 1998/02/26

けいじゅ@日本ラショナルソフトウェアです.

[ruby-list:6796] Re: Mutex/ConditionVariable/Queue

From: keiju@... (石塚圭樹 )
Date: 1998-02-26 15:40:49 UTC
List: ruby-list #6796
けいじゅ@日本ラショナルソフトウェアです.

In [ruby-list :06794 ] the message: "[ruby-list:6794] Re:
Mutex/ConditionVariable/Queue ", on Feb/26 20:42(JST) Shugo Maeda
writes:

>前田です。

>実際に実装してみました。
>SizedQueueもConditionVariableを使って書いてみましたが、きちんと
>動作確認していないのでうまく動くかわかりません(^^;
>
>Mutex#__cond_lockというのが苦しいところです。
>C++ならfriendにするんでしょうね(^^;

それもありますが. 本来必要のない実装がMutexに入り込んでいますよね. 

この場合は, MutexのサブクラスとしてConditionVariableに必要な機能を持つ
ものを実装した方が良くないでしょうか? すると, Mutex#__cond_lock ->
ConditionMutex#lock となって気持ち良くoverloadできますしね.

ついでに, そのサブクラスをConditionVariableのスコープに入れてしまいま
す.

さらに, ConditionVariable.newでmutexを渡すようになっていますが, 外部か
ら渡した方が良いんですかね? 勝手に必要がないとしてinitializeの中に組み
込んでみました.

# 必要ならば, ConditionVariable::ConditionMutex.new を行なう必要が出てく
# るので, もうちょっと工夫の必要があるかな?

すると以下のようなプログラムになりました. いかがなものでしょう?

# やっぱり動作確認しておりません.

class Mutex
#  オリジナルMutexと同じ
end

class ConditionVariable
  class ConditionMutex
    attr :owner
  
    def initialize
      super
      @cond_waiting = []
      @owner = nil
    end

    def try_lock
      if ret = super
	@owner = Thread.current
      end
      ret
    end

    def lock
      while (Thread.critical = true; @owner != nil)
	@cond_waiting.push(Thread.current)
	Thread.stop
      end
      @owner = Thread.current
      Thread.critical = false
    end

    def unlock
      if @owner != Thread.current
	raise ThreadError, "current thread not owner"
      end
      Thread.critical = true
      if @cond_waiting.empty?
	t = @waiting.shift
      else
	t = @cond_waiting.shift
      end
      @owner = nil
      Thread.critical = false
      t.run if t
    end
  end

  def initialize
    @mutex = ConditionMutex.new
    @waiting = []
    @waiting_mutex = Mutex.new
  end

  def synchronize
    @mutex.syncronize do
      yield
    end
  end

  def wait
    @mutex.unlock
    @waiting_mutex.synchronize {
      @waiting.push(Thread.current)
    }
    Thread.stop
    @mutex.lock
  end
  
  def signal
    if @mutex.owner != Thread.current
      raise ThreadError, "current thread not owner"
    end
    @waiting_mutex.synchronize {
      t = @waiting.shift
      t.run if t
    }
  end
    
  def broadcast
    if @mutex.owner != Thread.current
      raise ThreadError, "current thread not owner"
    end
    @waiting_mutex.synchronize {
      for t in @waiting
	t.run
      end
      @waiting.clear
    }
  end
  
  def num_waiting
    return @waiting.length
  end
end

class Queue
  def initialize
    @que = []
    @que_cond = ConditionVariable.new
  end

  def push(obj)
    @que_cond.synchronize {
      @que.push(obj)
      @que_cond.signal
    }
  end

  def pop(noblock = false)
    @que_cond.synchronize {
      if noblock and @que.length == 0
	raise ThreadError, "queue empty"
      end
      while @que.empty?
	@que_cond.wait
      end
      return @que.shift
    }
  end

  def empty?
    @que.length == 0
  end

  def length
    @que.length
  end
  alias size length
  
  def num_waiting
    return @que_cond.num_waiting
  end
end

class SizedQueue < Queue
  
  attr :max
  
  def initialize(max)
    @max = max
    @sized_que_cond = ConditionVariable.new
    super()
  end

  def push(obj)
    @sized_que_cond.synchronize {
      while @que.length >= @max
	@sized_que_cond.wait
      end
      super(obj)
    }
  end

  def pop(*args)
    @sized_que_cond.synchronize {
      obj = super
      if @que.length < @max
	@sized_que_cond.signal
      end
      return obj
    }
  end
  
  def max=(max)
    @sized_que_cond.synchronize {
      @max = max
      @sized_que_cond.broadcast
    }
  end
  
  def num_waiting
    return super + @sized_que_cond.num_waiting
  end
end


>
>class Mutex
>  
>  attr :owner
>  
>  def initialize
>    @waiting = []
>    @cond_waiting = []
>    @owner = nil
>  end
>
>  def locked?
>    return @owner != nil
>  end
>
>  def try_lock
>    result = false
>    Thread.critical = true
>    if @owner.nil?
>      @owner = Thread.current
>      result = true
>    end
>    Thread.critical = false
>    return result
>  end
>
>  def lock
>    while (Thread.critical = true; @owner != nil)
>      @waiting.push(Thread.current)
>      Thread.stop
>    end
>    @owner = Thread.current
>    Thread.critical = false
>  end
>
>  def unlock
>    if @owner != Thread.current
>      raise ThreadError, "current thread not owner"
>    end
>    Thread.critical = true
>    if @cond_waiting.empty?
>      t = @waiting.shift
>    else
>      t = @cond_waiting.shift
>    end
>    @owner = nil
>    Thread.critical = false
>    t.run if t
>  end
>
>  def synchronize
>    begin
>      lock
>      yield
>    ensure
>      unlock
>    end
>  end
>  
>  # DO NOT CALL THIS METHOD
>  def __cond_lock
>    while (Thread.critical = true; @owner != nil)
>      @cond_waiting.push(Thread.current)
>      Thread.stop
>    end
>    @owner = Thread.current
>    Thread.critical = false
>  end
>end
>
>class ConditionVariable
>  def initialize(mutex)
>    @mutex = mutex
>    @waiting = []
>    @waiting_mutex = Mutex.new
>  end
>  
>  def wait
>    @mutex.unlock
>    @waiting_mutex.synchronize {
>      @waiting.push(Thread.current)
>    }
>    Thread.stop
>    @mutex.__cond_lock
>  end
>  
>  def signal
>    if @mutex.owner != Thread.current
>      raise ThreadError, "current thread not owner"
>    end
>    @waiting_mutex.synchronize {
>      t = @waiting.shift
>      t.run if t
>    }
>  end
>    
>  def broadcast
>    if @mutex.owner != Thread.current
>      raise ThreadError, "current thread not owner"
>    end
>    @waiting_mutex.synchronize {
>      for t in @waiting
>	t.run
>      end
>      @waiting.clear
>    }
>  end
>  
>  def num_waiting
>    return @waiting.length
>  end
>end
>
>class Queue
>  def initialize
>    @que = []
>    @que_mutex = Mutex.new
>    @que_cond = ConditionVariable.new(@que_mutex)
>  end
>
>  def push(obj)
>    @que_mutex.synchronize {
>      @que.push(obj)
>      @que_cond.signal
>    }
>  end
>
>  def pop(noblock = false)
>    @que_mutex.synchronize {
>      if noblock and @que.length == 0
>	raise ThreadError, "queue empty"
>      end
>      while @que.empty?
>	@que_cond.wait
>      end
>      return @que.shift
>    }
>  end
>
>  def empty?
>    @que.length == 0
>  end
>
>  def length
>    @que.length
>  end
>  alias size length
>  
>  def num_waiting
>    return @que_cond.num_waiting
>  end
>end
>
>class SizedQueue < Queue
>  
>  attr :max
>  
>  def initialize(max)
>    @max = max
>    @sized_que_mutex = Mutex.new
>    @sized_que_cond = ConditionVariable.new(@sized_que_mutex)
>    super()
>  end
>
>  def push(obj)
>    @sized_que_mutex.synchronize {
>      while @que.length >= @max
>	@sized_que_cond.wait
>      end
>      super(obj)
>    }
>  end
>
>  def pop(*args)
>    @sized_que_mutex.synchronize {
>      obj = super
>      if @que.length < @max
>	@sized_que_cond.signal
>      end
>      return obj
>    }
>  end
>  
>  def max=(max)
>    @sized_que_mutex.synchronize {
>      @max = max
>      @sized_que_cond.broadcast
>    }
>  end
>  
>  def num_waiting
>    return super + @sized_que_cond.num_waiting
>  end
>end
>
>-- 
>前田 修吾
>

__
................................石塚 圭樹@日本ラショナルソフトェア...
----------------------------------->> e-mail: keiju@rational.com <<---

In This Thread