From: Robert Klemme Date: 2009-03-16T07:17:39+09:00 Subject: Re: does IO.read block? On 15.03.2009 23:02, Michael Malone wrote: > I have a setup where I am writing to a pipe in one process and reading > in another. I am closing the end I'm not using etc, but I have a new > problem. Having recently read that I was just getting lucky when it > came to my IO.write completing each time (probably due to Ruby's green > thread implementation in v1.8 and 'nice' scheduling) but now that the OS > has taken over scheduling, it tends to interrupt things when it damn > well feels like it, so I believe some of my write calls aren't > completing, so I've set up a loop like this: > > rescue Exception => error > ex_string = Marshal.dump(error) > ex_size = ex_string.bytesize > bytes_written = 0 > while bytes_written < ex_size > bytes_written += write_end.write(ex_string.slice!(bytes_written)) > end > ensure > write_end.close You do not seem to open the stream in this context, why do you close it here? Or do you have a pattern like write_end = ... # open begin ... rescue ... ensure write_end.close end > end > end IMHO you can simplify that do rescue Exception => error Marshal.dump(error, write_end) end Which should also be more efficient since the looping is done in C code. > and in the other process, I currently make just one call to > read_end.read() so my question is, is this guaranteed to get all of the > bytes written through multiple calls to write or do I need to set up a > similar loop on the read end? like > > while !(read_end.eof?) > string += read_end.read > end > > Or does read_end.read block until it finds EOF? Yes, that's what it does: http://www.ruby-doc.org/core/classes/IO.html#M002295 But again, I would just do obj = Marshal.read(read_end) Which, again is more efficient since you do not need the additional buffer and looping is done in C code. > Can anyone tell me what happens when read_end.read is re-scheduled > partway through? Or is that guaranteed to finish? I am not sure what you mean by "rescheduled". Even if the OS preempts execution of this process or thread it will continue at the same location of the stream and semantics of the methods do not change. Kind regards robert