Mutex

Hi,
I have a trouble using the ConditionVariable and Mutex Class ,
Actualy , I’m tryin’ to make a Semaphore to manage Threads
a simple semaphore with its 2 famous methods looks like :

def acquire()

raise "Interrupted Thread " if (!Thread.current.alive?)
@mutex.synchronize {
 while @permits < 1
   @cv.wait(@mutex)
 end
@permits = @permits - 1
}

end

def release()
@mutex.synchronize{

  @permits += 1
  @cv.signal

  }

end

But When I call The acquire Method later

I get : `wait’: stopping only thread (ThreadError)

SomeOne has an idea ??

Thx;)

2010/2/15 Mido P. [email protected]:

  @cv.wait(@mutex)
 @cv.signal

SomeOne has an idea ??
Not without the full code. What you showed looks OK.

Kind regards

robert

require ‘thread’
class Semaphore

Thread.abort_on_exception = true
attr_accessor :permits, :mutex, :cv

def initialize ( permits )

  @permits = permits
  @mutex = Mutex.new
  @cv = ConditionVariable.new

end

def acquire()

raise "Interrupted Thread " if (!Thread.current.alive?)
@mutex.synchronize {
while @permits < 1
   @cv.wait(@mutex)
end
@permits = @permits - 1
}

end

def release()
@mutex.synchronize{

  @permits += 1
  @cv.signal

  }

end

end


class Process < Thread

def initialize()
super(){

@sem=Semaphore.new(0)

}
end

def run()


@sem.acquire()

end

The problem is that I should call the semaphore later , not within
initialization of the process !!

2010/2/15 Mido P. [email protected]:

require ‘thread’
class Semaphore

Thread.abort_on_exception = true

Why do you place that inside the class? This is a global setting.

end


class Process < Thread

def initialize()
super(){

@sem=Semaphore.new(0)

IIRC semaphores are typically initialized with a positive value, i.e.
something larger than 0. If you think about it, init with 0 does not
make too much sense.

The problem is that I should call the semaphore later , not within
initialization of the process !!

You can’t define a class Process like this because that class exists
already.

One more hint: for more robust access I suggest to add this method to
your Semaphore class:

def synchronize
acquire

begin
yield
ensure
release
end
end

Kind regards

robert

2010/2/15 Caleb C. [email protected]:

the init value is exactly what’s needed.
Right you are. Although I’d say that a condition variable is probably
a better tool for that.

Mido, what do you want this for? Mutual exclusion? (But then why not
just use a Mutex?) Signaling? Counting semaphore?

You might consider using a (sigh) Queue or SizedQueue instead. Even
tho it’s kinda silly to use a Queue when all you’re ever putting on or
taking off the queue is instances of TrueClass.

Hm, in that case I’d prefer a semaphore.

It used to be possible to fake signaling semaphore behavior by
creating a Mutex then immediately locking it. That doesn’t work
anymore, tho; the thread that unlocks a Mutex now has to be the same
one that locked it.

That is not needed. Please see my test - I could not reproduce the
behavior reported.

Kind regards

robert

Thx for your Help !!

well , actually , I tried first of all to start a ‘p’ Process and to
make it wait , ( for the mutex signal ), then later on my code , I will
lunch a function that will increment the Value on the Semaphore , that
my ‘p’ could enter the Mutex section and do its work !!

So , I think the Error I did , is That I initialize the process without
tellin’ him to wait ( without the acquire function ) , and when I tried
to call it later , it give me that error .

now wihtin the Initialize , I added the call to acquire , Somethg like ;

require ‘Semaphore’
class MyProcess < Thread
def intializer ()
super(){
… # Init Some Variables
@semBegin = Semaphore.new(0)
@semEnd = Semaphore.new(0)
@semBegin.acquire() # here since the value is 0 , he will wait

… # Code to be exectured after recieving the Mutex Signal

 }

end

end
#SomeWhere I will increment the Semaphore Value to wake up my process
and push it to work !!

in this way , I could keep my process Alive during the Application
(waitin’)… otherwise the process will ends when nothing is left to do
!!

:wink:

On 2/15/10, Robert K. [email protected] wrote:

2010/2/15 Mido P. [email protected]:

@sem=Semaphore.new(0)

IIRC semaphores are typically initialized with a positive value, i.e.
something larger than 0. If you think about it, init with 0 does not
make too much sense.

It depends on what you’re using the semaphore for. If it’s to be used
for locking, you’re right. If it’s a signaling semaphore, then 0 for
the init value is exactly what’s needed.

Mido, what do you want this for? Mutual exclusion? (But then why not
just use a Mutex?) Signaling? Counting semaphore?

You might consider using a (sigh) Queue or SizedQueue instead. Even
tho it’s kinda silly to use a Queue when all you’re ever putting on or
taking off the queue is instances of TrueClass.

It used to be possible to fake signaling semaphore behavior by
creating a Mutex then immediately locking it. That doesn’t work
anymore, tho; the thread that unlocks a Mutex now has to be the same
one that locked it.

On 2/16/10, Robert K. [email protected] wrote:

2010/2/15 Caleb C. [email protected]:

It depends on what you’re using the semaphore for. If it’s to be used
for locking, you’re right. If it’s a signaling semaphore, then 0 for
the init value is exactly what’s needed.

Right you are. Although I’d say that a condition variable is probably
a better tool for that.

It may be, but I’ve never understood condition variables properly.
They seem to be semaphores with some additional semantics but it never
made enough sense to me that I felt I could use them with
confidence… the docs never helped. I was raised on semphores, and
that’s all I know. :slight_smile: If you actually understand condition variables
and how to use them, could you kindly explain them to me? I would be
grateful.

On 02/16/2010 08:19 PM, Caleb C. wrote:

made enough sense to me that I felt I could use them with
confidence… the docs never helped. I was raised on semphores, and
that’s all I know. :slight_smile: If you actually understand condition variables
and how to use them, could you kindly explain them to me? I would be
grateful.

Ah, my posting did not make it through the gateway - probably because I
attached the code. Here it is again: sem.rb · GitHub

Basically a condition variable is just a special signaling mechanism -
you can use any number of condition variables with a mutex or monitor in
order to signal different conditions. Waiting threads are then woken up
efficiently. For example, in a bounded queue you can have two condition
variables @queue_has_room and @data_available with obvious semantics
(@queue_has_room is signaled whenever something is taken from the queue,
@data_available is signaled whenever something is put into the queue).

Technically when you wait on a condition variable you must own the
monitor / mutex. Your thread is blocked and the lock is released. When
a signal occurs for this condition variable, waiting threads are woken
and after the signal thread releases the lock any of the waiting thread
obtains it and continues. That way you can selectively wake up threads
which is more efficient to just wake up all threads waiting for a
monitor.

If you want to dig deeper into concurrency I can recommend Doug Lea’s
excellent book (even though it is about Java). http://g.oswego.edu/

Kind regards

robert