hi.
I’m writing tcp server and I want to know:
-
how can I block thread until some event will occur w/o overhead?
(i.e. not timer, but something like semaphore); -
how can I interrupt IO::select() call from main thread?
thank you/
hi.
I’m writing tcp server and I want to know:
how can I block thread until some event will occur w/o overhead?
(i.e. not timer, but something like semaphore);
how can I interrupt IO::select() call from main thread?
thank you/
Daniel F. [email protected] wrote:
hi.
I’m writing tcp server and I want to know:
- how can I block thread until some event will occur w/o overhead?
(i.e. not timer, but something like semaphore);
A Conditionariable, IO.select (which you already knew :),
or a blocking read on any socket or pipe.
- how can I interrupt IO::select() call from main thread?
Create a socketpair or pipe and and write to it from the main thread.
It’s also useful with the self-pipe trick[1]
If you’re stuck on a platform without UNIX sockets or pipes, you can
also connect to your main TCPServer (or another private one) to
wakeup from select.
A Conditionariable, IO.select (which you already knew :),
or a blocking read on any socket or pipe.
Creating a new socketpair/pipe is pretty too much imho (no matter it’s a
very
small object, but it exists and must be handled). I thought about some
kind of
semaphore, then process would look like:
in thread:
semaphore.wait_for_event
in main:
semaphore.emit_event
Create a socketpair or pipe and and write to it from the main thread.
It’s also useful with the self-pipe trick[1]If you’re stuck on a platform without UNIX sockets or pipes, you can
also connect to your main TCPServer (or another private one) to
wakeup from select.
that makes the same trouble as described above: one more file
descriptor,
which is overhead. I knew this solution and used it in C, but I thought
ruby is able to provide some better solution.
Hi Daniel,
On Thu, Jul 9, 2009 at 8:28 PM, Daniel F. [email protected] wrote:
If you’re stuck on a platform without UNIX sockets or pipes, you can
also connect to your main TCPServer (or another private one) to
wakeup from select.that makes the same trouble as described above: one more file
descriptor,
which is overhead. I knew this solution and used it in C, but I thought
ruby is able to provide some better solution.
Look up EventMachine - it’s what you want without re-inventing the
wheel.
John
Look up EventMachine - it’s what you want without re-inventing the
wheel.John
thank you, thats exaclty what I need
Creating a new socketpair/pipe is pretty too much imho (no matter it’s a
very
small object, but it exists and must be handled). I thought about some
kind of
semaphore, then process would look like:in thread:
semaphore.wait_for_event
in main:
semaphore.emit_event
I’ve found the way how to do this, here is code + example:
#!/usr/bin/ruby -w
require ‘thread’
class MassSemaphoreEmulator
def initialize
@mutex=Mutex.new # we can have race condition on a variable below,
so avoid it with mutex
@waiting_threads=[]
end
def wait
@mutex.synchronize { @waiting_threads<<Thread.current } # add
current thread to waiting ones
Thread.stop
end
def signal
@mutex.synchronize do # wakeup all threads
@waiting_threads.each {|t| t.wakeup}
@waiting_threads.clear
end
end
end
semaphore=MassSemaphoreEmulator.new
threads=(1…10).map do |i|
Thread.new(i*1) do |v|
print “#{v} is waiting…\n”
semaphore.wait # wait for our mutex
print “#{v} got signal.\n”
end
end
semaphore.signal # get all waiting threads up
threads.each {|t| t.join}
I’ve also tried to do something with ConditionalVariable, but no luck,
it didn’t stop waiting threads.
now I need to find a way for interrupting select call
But overall I might suggest eventmachine or revactor for what you want.
Cheers!
=r
I’m using eventmachine atm, revactor seems to be easier and simpler, but
it requires 1.9 ruby
- how can I block thread until some event will occur w/o overhead?
(i.e. not timer, but something like semaphore);
select [or in 1.9 fibers].
- how can I interrupt IO::select() call from main thread?
You’d have to have some socket within it that will interrupt.
like interruptor = TCPSocket.new( ‘’, 3333)
select [interruptor], nil, nil
then in other thread
a TCPSocket.new(‘localhost’, 3333)
a.send ‘a’
something like that
Or if you didn’t care about thread safety you could use Thread.raise
[scary].
But overall I might suggest eventmachine or revactor for what you want.
Cheers!
=r
This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.
Sponsor our Newsletter | Privacy Policy | Terms of Service | Remote Ruby Jobs