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)
Not without the full code. What you showed looks OK.
Kind regards
robert
···
2010/2/15 Mido Peace <mido.peace@gmail.com>:
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)
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)
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.
\.\.\.
}
end
def run()
... @sem.acquire()
end
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:
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/15/10, Robert Klemme <shortcutter@googlemail.com> wrote:
2010/2/15 Mido Peace <mido.peace@gmail.com>:
@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.
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.
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.
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
!!
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. If you actually understand condition variables
and how to use them, could you kindly explain them to me? I would be
grateful.
···
On 2/16/10, Robert Klemme <shortcutter@googlemail.com> wrote:
2010/2/15 Caleb Clausen <vikkous@gmail.com>:
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.
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
···
On 02/16/2010 08:19 PM, Caleb Clausen wrote:
On 2/16/10, Robert Klemme <shortcutter@googlemail.com> wrote:
2010/2/15 Caleb Clausen <vikkous@gmail.com>:
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. If you actually understand condition variables
and how to use them, could you kindly explain them to me? I would be
grateful.