non-blocking I/O in go

5,974 views
Skip to first unread message

bemi

unread,
Mar 26, 2012, 7:27:19 PM3/26/12
to golang-nuts
How to do non-blocking I/O in go?, I can't find any select(), fcntl()
calls in go.

In particular I would like to do non-blocking TCP sockets, so I would
like to be somehow be able to switch file descriptors to non-blocking
and poll them.

Thanks,
Milan

Rob Lapensee

unread,
Mar 26, 2012, 7:31:40 PM3/26/12
to golang-nuts
I did it in the past by creating a go routine and channel,
the go routine writes the data from the socket into a channel,
then use select on the channel (outside the go routine) to wait for
anything from the channel,
default on the select will keep the select from blocking.

Paul Borman

unread,
Mar 26, 2012, 8:04:33 PM3/26/12
to Rob Lapensee, golang-nuts
To me, a major feature of goroutines and channels is to eliminate the need for non-blocking/async operations.  You just spin off a goroutine and, as Rob says, use a channel to get the data back (and use select statements if you really need non-blocking).  I think you will find with Go you can get rid of a lot of that.  No need to write event loops and do your coding "inside-out".  Just write it naturally and let Go take case of the rest.  If you really think you need non-blocking operations, think again.  You might just find out you don't and it is easier without!

    -Paul

bemi

unread,
Mar 26, 2012, 8:16:56 PM3/26/12
to golang-nuts
> > I did it in the past by creating a go routine and channel

I am thinking to do something similar too. My concern is: if given the
Reader and Writer interface have under the hood same socket file
descriptor, is it safe to call Read(), Write() in parallel from
different go routines? ( E.g what if the read system call detects the
error while the write system call blocks in separate thread? does the
write system call ever exit?, if not then the writer thread will be
deadlocked.).

Seems that Read() and Write() interfaces are implemented so that they
can be used in such scenario. They just read, write as many bytes as
possible but there's no mention in the documentation that they can be
safely called in parallel.

Rob Lapensee

unread,
Mar 26, 2012, 8:25:46 PM3/26/12
to golang-nuts
I seem to recall that the go authors on this list said you could do
just that,
read from one go routine, write from another go routine, safely,
As long as two go routines did not read at the same time, or two go
routines did not write at the same time.
this is all from memory, so somebody can correct me if I'm wrong.

unfortunately I could not find the link that had this discussion.
Message has been deleted

bemi

unread,
Mar 26, 2012, 8:50:53 PM3/26/12
to golang-nuts
> To me, a major feature of goroutines and channels is to eliminate the need
> for non-blocking/async operations. You just spin off a goroutine and, as
> Rob says, use a channel to get the data back (and use select statements if
> you really need non-blocking)


Great!, thanks for the confirmation that go was designed with this in
mind and handles all correctly. Then I am going to use 2 parallel go
routines for read and write from same socket and routines themselves
will use channels to send / receive from / to application any
available data hereby need for non-blocking access shall be
eliminated.
Reply all
Reply to author
Forward
0 new messages