Nonblocking TCPSocket in multithread software


#1

Hi!

Why this blocks?

a = Thread.new do
s = TCPSocket.new(‘localhost’, 4343)
s.nonblock = true
p s.read # it block’s here no matter what i do
end
a.join

… and how to make it nonblock?

It works fine if i drive it in main thread.

Thnx: Artsi


#2

It seems work if i lock thread… funny… :slight_smile:

a = Thread.new do
s = TCPSocket.new(‘localhost’, 4343)
s.nonblock = true
Thread.critical {
p s.read # it block’s here no matter what i do
}
end
a.join

  • Artsi

2005/12/16, Arto P. removed_email_address@domain.invalid:


#3

pah… now it just dont do nothing…

2005/12/16, Arto P. removed_email_address@domain.invalid:


#4

http://www.ruby-talk.org/cgi-bin/scat.rb/ruby/ruby-talk/158720

… sad … huoh…

2005/12/16, Arto P. removed_email_address@domain.invalid:


#5

Arto P. removed_email_address@domain.invalid writes:

Hi!

Why this blocks?

a = Thread.new do
s = TCPSocket.new(‘localhost’, 4343)
s.nonblock = true
p s.read # it block’s here no matter what i do

I expect it to block. All IO’s buffered I/O methods (puts, prints, read,
write,
etc.) are blocking operations.

The utility of nonblock comes if you use unbuffered I/O methods:
sysread, syswrite, recv, send, etc.

YS.


#6

From: “Arto P.” removed_email_address@domain.invalid

p s.read # it block’s here no matter what i do
end
a.join

… and how to make it nonblock?

My version of Ruby (1.8.2) doesn’t have the #nonblock method.

So I use:

@sock.fcntl(Fcntl::F_SETFL, @sock.fcntl(Fcntl::F_GETFL) |
Fcntl::O_NONBLOCK)

Maybe try:

a = Thread.new do
s = TCPSocket.new(‘localhost’, 4343)

s.fcntl(Fcntl::F_SETFL, s.fcntl(Fcntl::F_GETFL) | Fcntl::O_NONBLOCK)
print dat while dat = s.recv(65536)
end

Note that I’m using #recv instead of #read… Maybe this will help?

Hope this helps,

Regards,

Bill


#7

In article removed_email_address@domain.invalid,
Yohanes S. removed_email_address@domain.invalid writes:

I expect it to block. All IO’s buffered I/O methods (puts, prints, read, write,
etc.) are blocking operations.

Agreed.

The utility of nonblock comes if you use unbuffered I/O methods:
sysread, syswrite, recv, send, etc.

Unfortunately they blocks if there are multiple threads.

Apart from that syswrite (and other unbuffered writing
methods) blocks unless O_NONBLOCK.

Formar problem can be solved by IO.select.
Later problem can be solved by O_NONBLOCK.

I think it is useful that some utility nonblocking methods
to care above issues automatically. However it is quite
difficult to propose method names which matz accept.


#8

On Sat, 17 Dec 2005, Tanaka A. wrote:

I think it is useful that some utility nonblocking methods to care above
issues automatically. However it is quite difficult to propose method names
which matz accept.

i respectfully suggest, to matz, that this should not stand in the way.
this
issue has come up too many times to let naming stand in the way. there
is
little that an ‘alias’ might not solve at a later date. something
simple,
like prefacing every such io method with ‘nb_’ would, at the least, be
easily
understood, even if inelegant.

kind regards.

-a


#9

Hi bill!

I try your example, and well it works little better but it is not what
i search…

I try to implemented multiplexed architecture, and the Thread still
blocks and it is not acceptable, i even cannot see difference if i
remove file descriptor mod line or if i leave it… btw. i dont know
nothing programming native file descriptors. maby i should read it.

Now, i would like to get clear answer… is it possible to implement
clean multiplexed socket architecture, like with java.nio?? (yes, i
was java programmer before i found ruby on rails :))

Thanks guys, Artsi

2005/12/16, Bill K. removed_email_address@domain.invalid:


#10

In article removed_email_address@domain.invalid,
removed_email_address@domain.invalid writes:

i respectfully suggest, to matz, that this should not stand in the way. this
issue has come up too many times to let naming stand in the way. there is
little that an ‘alias’ might not solve at a later date. something simple,
like prefacing every such io method with ‘nb_’ would, at the least, be easily
understood, even if inelegant.

matz?


#11

In article removed_email_address@domain.invalid,
Arto P. removed_email_address@domain.invalid writes:

I try to implemented multiplexed architecture, and the Thread still
blocks and it is not acceptable, i even cannot see difference if i
remove file descriptor mod line or if i leave it… btw. i dont know
nothing programming native file descriptors. maby i should read it.

How do you multiplex I/O? IO.select?

If you use IO.select and call IO#sysread only wnen IO.select
notify readability, it should not block.


#12

ah… the magic select… :slight_smile:

I tried it some time ago, but i couldnt get it work, i cant remember
maby it was syntax error, i have inspect ruby only couple weeks…
But this was what i have searched. Thank you Tanaka!!

2005/12/19, Tanaka A. removed_email_address@domain.invalid: