Thread IO


#1

What can I use as a general purpose duplexed IO object to communicate
via data streams between two threads? I would like something similar to
TCPSocket, but without the need to communicate via a network port.


#2

That’s a pretty standard way to do IPC and is generally a good idea.
Also
your code works for me. What ruby implementation are you using?

On Thu, Feb 26, 2009 at 8:50 PM, Martin C.


#3

Martin C. wrote:

What can I use as a general purpose duplexed IO object to communicate
via data streams between two threads? I would like something similar to
TCPSocket, but without the need to communicate via a network port.

I’ve thought of creating two pipes (because I understand by nature that
one end is read-only and the other write-only) and then giving each
thread a read end and a write end, as shown below. The problem is that
this hangs indefinitely, perhaps just highlighting my lack of
understanding of how IO works (if that is the case, please be so kind as
to put me out of my misery and point me to a good primer).

So, here goes:

gui_rd, ctr_wr = IO.pipe
ctr_rd, gui_wr = IO.pipe

gui = Thread.new(gui_rd, gui_wr) {|gui_rd, gui_wr|
gui_wr << “I’ve got something for you\n”
puts gui_rd.gets
}

ctr = Thread.new(ctr_rd, ctr_wr) {|ctr_rd, ctr_wr|
puts ctr_rd.gets
ctr_wr << “Right back at you\n”
}

gui.join
ctr.join


#4

I am running on
ruby 1.8.6 (2007-09-24 patchlevel 111) [i386-mswin32]
(from the one-click installer)


#5

I have just tried it on

ruby 1.8.7 (2008-08-11 patchlevel 72) [i486-linux]

and there it works!

If this is a Windows issue, is there possibly a workaround?


#6

Martin C. wrote:

I am running on
ruby 1.8.6 (2007-09-24 patchlevel 111) [i386-mswin32]
(from the one-click installer)

Oh yes, and I’m running on Windows XP SP2 if that makes a difference.


#7

2009/2/26 Martin C. removed_email_address@domain.invalid:

What can I use as a general purpose duplexed IO object to communicate
via data streams between two threads? I would like something similar to
TCPSocket, but without the need to communicate via a network port.

You can use class Queue.

Kind regards

robert


#8

Martin C. wrote:

What can I use as a general purpose duplexed IO object to communicate
via data streams between two threads? I would like something similar to
TCPSocket, but without the need to communicate via a network port.

Socket.pair is the low-level way of doing this (equivalent to
socketpair())

But if it’s just between two Ruby threads, I’d use Queue or SizedQueue.
See thread.rb in the standard library.


#9

Thanks very much Robert and Brian.

This might be what I am looking for. I will do some investigation to see
if I can use this instead.

Now, it would still be interesting to know why the pipes worked on Linux
but not on Windows.


#10

On Thu, Feb 26, 2009 at 11:22 PM, Martin C.
removed_email_address@domain.invalidwrote:

Thanks very much Robert and Brian.

This might be what I am looking for. I will do some investigation to see
if I can use this instead.

Now, it would still be interesting to know why the pipes worked on Linux
but not on Windows.

Good question. Might be a bug. Not sure how pipes are implemented in
windows
but in linux they’re native. Maybe it would work in jruby.


#11

Thanks Dylan.

It turns out that what I needed after all was the Queue solution, so
fortunately I won’t have to rely on pipes at this point in time.


#12

The other thing to note is that this does not happen with TCPSocket
(again on Windows in my case), because the following works for me:

require ‘socket’
require ‘gserver’

class MyServer < GServer
def initialize(port=9876, *args)
super(port, *args)
end
def serve(io)
puts io.gets
stop
end
end

server = MyServer.new.start
TCPSocket.new(“localhost”, 9876) << “I have found you!\n”
server.join

So other than the pipes and the sockets, is there another IO object I
can use to communicate between two threads?