3 ms·
Sorry for being unclear. You don't interrupt the read as such. You interrupt the select. The usual trick on POSIX is to use a self-pipe, since select()/epoll()
by lobster_johnson 10y ago
Sorry for being unclear. You don't interrupt the read as such. You interrupt the select.
The usual trick on POSIX is to use a self-pipe, since select()/epoll() only work on file descriptors and not, say, pthread primitives. Windows is slightly better here: WaitForMultipleObjects supports waiting on any primitive that supports blocking, so you wait on the socket + on an event object, and signaling the event object will unblock the wait. Windows also has completion ports, and the APIs are generally more extensive (not a fan of Windows, but they got this part very right).
I do understand why Go is the way it is. But it's important to recognize that it's a compromise in design that inherently reduces your flexibility — such as in this particular case. I don't think there's anything technically preventing Go from supporting non-blocking I/O, though.
Channels and FDs/sockets are both conceptually multi-valued; what did you mean by that? One major difference is that reads can fail with an error, and channel reads can't.
Edit: Also, I didn't mean that select{} on a file descriptor ought to actually return data. It would be more appropriate for it to yield a true/false value to signal that the FD has data, so you'd do "case <-fd: fd.Read(bufSize)".
- nothrabannosir 10y agoAgree with everything. Just to reply to this: > Channels and FDs/sockets are both conceptually multi-valued; what did you mean by that? I was trying to preempt pedantry, but ended up being the pedant myself :P "You can simulate multi valued responses in a channel by passing a struct."
- mentat 10y agoYou can select on the read and an time.After channel which "interrupts" the select for a timeout.
- lobster_johnson 10y agoYou can't select on a read, though. select{} only works on channels. You can run the read in a separate goroutine, but that doesn't stop the read from happening.
- tptacek 10y agoYou can't use the language "select", but you can call the select(2) system call.
- lobster_johnson 10y agoIndeed, someone already pointed this out: https://news.ycombinator.com/item?id=13332847 https://news.ycombinator.com/item?id=13332847.
- echlebek 10y agoHow is your "case <-fd: fd.Read(bufSize)" not a race condition?
- atombender 10y agoRace condition? It's no different from select() followed by recv() in C. But I'm talking about semantics here, not suggesting that this would necessarily be how you'd write it. The main idea was allowing select{} to work on non-channel sources of notifications, such as file descriptors.