-
Notifications
You must be signed in to change notification settings - Fork 18k
x/sys/unix: strange behaviour on unix.Select #61225
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Can you add the actual for loop to your code sample? |
@rittneje Hello, the code is as follows func (g *Gbus) SendThenRecv(sendMsg []byte, timo int) (frame []byte, err error) {
var (
fd int
nfds int
readSet unix.FdSet
tv unix.Timeval
buf []byte // read buffer
nbytes int // how many bytes read
)
// func (s *S) Write(buf []byte)(n int, err error) {
// n, err = unix.Write(s.fd, buf)
// return
// }
if _, err = g.ser.Write(sendMsg); err != nil {
return
}
// func (s *S) Tcdrain() (err error) {
// _, _, eno := unix.Syscall(unix.SYS_IOCTL, uintptr(s.fd), uintptr(unix.TCSBRK), uintptr(1))
// if eno != 0 {
// err = errors.New(eno.Error())
// }
// return
// }
g.ser.Tcdrain()
fd = g.ser.Fd() // get serial fd
frame = make([]byte, 0)
readSet.Zero()
readSet.Set(fd)
tv.Sec = 0
tv.Usec = timo * 1000
mlog.Debug.Println("starting select")
if nfds, err = unix.Select(fd+1, &readSet, nil, nil, &tv); err != nil {
mlog.Error.Println(err)
return
}
if nfds > 0 {
if readSet.IsSet(fd) {
buf = make([]byte, 1024)
// func (s *S) Read(buf []byte) (n int, err error) {
// n, err = unix.Read(s.fd, buf)
// return
// }
if nbytes, err = g.ser.Read(buf); err != nil { // read data of serial
mlog.Error.Println(err)
return
}
if nbytes > 0 {
frame = append(frame, buf[:nbytes]...) // package as a frame
}
}
} else if nfds == 0 {
mlog.Debug.Println("timeout")
err = eAckTimeOut
return
} else {
err = eUnknow
return
}
return
} func main() {
var (
frame []byte
err error
)
// ...
sendMsg := []byte{0x01, 0x02, 0x03} // some serialized data
for {
if frame, err = g.SendThenRecv(sendMsg, 100); err != nil {
// handle error
// ...
time.Sleep(20 * time.Millisecond)
continue
}
// handle received data
// ...
time.Sleep(20 * time.Millisecond)
}
// ..
} |
Per https://pubs.opengroup.org/onlinepubs/9699919799/functions/pselect.html#tag_16_400_05, The Go runtime sometimes self-signals in order to preempt a running goroutine. You should assume that any syscall that is permitted to return |
@bcmills If that were the culprit, wouldn't |
Try running the program under |
Timed out in state WaitingForInfo. Closing. (I am just a bot, though. Please speak up if this is a mistake or you have the requested information.) |
What version of Go are you using (
go version
)?Does this issue reproduce with the latest release?
What operating system and processor architecture are you using (
go env
)?What did you do?
I'm using "Select" to get serial port data, but I'm experiencing some strange behavior. Instead of waiting for the specified timeout duration, it immediately times out.
code:
Loop calling the above code
What did you expect to see?
What did you see instead?
Please take a look at the time in the last two lines. The difference in time between the two is only about 3 milliseconds. But the timeout time set in the code is 100 milliseconds.
The text was updated successfully, but these errors were encountered: