Hello,
I observed that even if every thread in a program creates it's own
Socket, but all to the same Server, then this is not thread-safe.
It is the same situation as if every thread shared the same Socket
without any mutexes. I observed this with TCPSockets, UNIXSockets ans
UDPSockets.
I run Kernel 2.6.14.2, ruby 1.8.4 (2005-12-24) [i686-linux]
The short source code below produces the following output on the server.
If I enabled the mutex (the 3 lines commented out) it would work better.
Got: thread[16] says 65
Got: thread[19] says 68thread[17] says 20
Got:
Got: thread[24] says 97
Got: thread[8] says 64thread[26] says 17thread[13] says 43
Got:
Got:
Got: thread[7] says 84
Got: thread[0] says 78thread[18] says 37
Got: thread[27] says 98
Got:
Got: thread[18] says 13
Got: thread[11] says 19
Got: thread[1] says 91thread[26] says 18
Got:
Got: thread[1] says 53
Got: thread[19] says 42
# First start the server with:
# ruby tcpsockets.rb server
# Then start the client which spawns several threads:
# ruby tcpsockets.rb
require 'socket'
require 'monitor'
if ARGV[0] == 'server'
threads = []
server = TCPServer.new 'localhost', 8889
putslock = Monitor.new
while socket = server.accept
t = Thread.new(socket) do |sock|
while str = sock.gets
putslock.synchronize do
puts "Got: #{str}"
end
end
end
threads << t
end
threads.each do |t| t.join end
else
Thread.abort_on_exception = true
#socketlock = Monitor.new
threads = []
30.times do |i|
t = Thread.new(i) do |ii|
count = 0
socket = TCPSocket.new 'localhost', 8889
puts "Using socket #{socket.object_id}"
while count < 10
#socketlock.synchronize do
socket.puts "thread[#{ii}] says #{Kernel.rand 100}"
socket.flush
#end
sleep Kernel.rand * 0.3
count += 1
end
end
threads << t
end
threads.each do |t| t.join end
end
Is this known/intended behavior?
thanks and a good day!
Dominik