Dans cet article, l'éditeur PHP Zimo répondra à votre question sur SetDeadline/SetReadDeadline/SetWriteDeadline qui ne fonctionne pas sur les fichiers lors de l'utilisation de os.File.Fd() dans Golang. Dans Golang, ces méthodes sont utilisées pour fixer la date limite des fichiers, mais elles peuvent parfois être invalides. Nous explorerons ensuite les causes possibles et proposerons des solutions pour garantir le bon fonctionnement de ces méthodes.
J'utilise os.File.SetReadDeadline
和 os.File.ReadFull
的组合。但即使使用 SetReadDeadline
,我设置的截止日期也被完全忽略,并且 ReadFull
le blocage permanent. pourquoi donc?
Informations supplémentaires : je lance des IOCTLS sur le fichier, donc os.File.Fd() est nécessaire pour obtenir le descripteur de fichier.
tl; Docteur :
Utilisez os.file.fd()
后,在文件上使用 syscall.setnonblock(fd.fd(), true)
Cela est dû à read
dans 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 } }
Si le fichier est défini en mode bloquant, le premier n, err := ignoringeintrio(syscall.read, fd.sysfd, p)
将永远阻塞。 waitread
ne sera exécuté que si le fichier est ouvert en mode non bloquant. Mais j’ai ouvert le fichier en mode non bloquant, alors que s’est-il passé ?
os.file.fd()
le casse :
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) }
fd()
Définissez toujours les fichiers sur blocage. Par conséquent, nous devons annuler l’opération avant d’attendre la lecture du sondage. Donc :
Utilisez os.file.fd()
后,在文件上使用 syscall.setnonblock(fd.fd(), true)
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!