Dalam artikel ini, editor PHP Zimo akan menjawab soalan anda tentang SetDeadline/SetReadDeadline/SetWriteDeadline tidak berfungsi pada fail apabila menggunakan os.File.Fd() di Golang. Di Golang, kaedah ini digunakan untuk menetapkan tarikh akhir fail, tetapi kadangkala ia mungkin tidak sah. Seterusnya, kami akan meneroka kemungkinan punca dan menyediakan penyelesaian untuk memastikan kaedah ini berfungsi dengan betul.
Saya menggunakan os.File.SetReadDeadline
和 os.File.ReadFull
的组合。但即使使用 SetReadDeadline
,我设置的截止日期也被完全忽略,并且 ReadFull
menyekat selama-lamanya. kenapa begitu?
Maklumat tambahan: Saya sedang melancarkan beberapa IOCTLS ke fail, jadi os.File.Fd() diperlukan untuk mendapatkan deskriptor fail.
tl;
Gunakanos.file.fd()
后,在文件上使用 syscall.setnonblock(fd.fd(), true)
read
dalam golang unix:
func (fd *fd) read(p []byte) (int, error) { if err := fd.readlock(); err != nil { return 0, err } defer fd.readunlock() if len(p) == 0 { // if the caller wanted a zero byte read, return immediately // without trying (but after acquiring the readlock). // otherwise syscall.read returns 0, nil which looks like // io.eof. // todo(bradfitz): make it wait for readability? (issue 15735) return 0, nil } if err := fd.pd.prepareread(fd.isfile); err != nil { return 0, err } if fd.isstream && len(p) > maxrw { p = p[:maxrw] } for { n, err := ignoringeintrio(syscall.read, fd.sysfd, p) if err != nil { n = 0 if err == syscall.eagain && fd.pd.pollable() { if err = fd.pd.waitread(fd.isfile); err == nil { continue } } } err = fd.eoferror(n, err) return n, err } }
yang pertama hanya akan dilaksanakan jika fail dibuka dalam mod tidak menyekat. Tetapi saya telah membuka fail dalam mod tidak menyekat, jadi apa yang berlaku? n, err := ignoringeintrio(syscall.read, fd.sysfd, p)
将永远阻塞。 waitread
Pelaksanaan
os.file.fd()
memecahkannya :
func (f *File) Fd() uintptr { if f == nil { return ^(uintptr(0)) } // If we put the file descriptor into nonblocking mode, // then set it to blocking mode before we return it, // because historically we have always returned a descriptor // opened in blocking mode. The File will continue to work, // but any blocking operation will tie up a thread. if f.nonblock { f.pfd.SetBlocking() } return uintptr(f.pfd.Sysfd) }
Sentiasa tetapkan fail untuk menyekat. Oleh itu, kita mesti membatalkan operasi sebelum menunggu undian dibaca. Oleh itu: fd()
os.file.fd()
后,在文件上使用 syscall.setnonblock(fd.fd(), true)
Atas ialah kandungan terperinci GOLANG: Mengapa SetDeadline/SetReadDeadline/SetWriteDeadline tidak berfungsi untuk fail apabila menggunakan os.File.Fd()?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!