GOLANG: Warum funktionieren SetDeadline/SetReadDeadline/SetWriteDeadline nicht für Dateien, wenn os.File.Fd() verwendet wird?

PHPz
Freigeben: 2024-02-09 08:30:21
nach vorne
1067 Leute haben es durchsucht

GOLANG:为什么在使用 os.File.Fd() 时 SetDeadline/SetReadDeadline/SetWriteDeadline 对文件不起作用?

In diesem Artikel beantwortet der PHP-Editor Zimo Ihre Frage, ob SetDeadline/SetReadDeadline/SetWriteDeadline bei Dateien nicht funktioniert, wenn os.File.Fd() in Golang verwendet wird. In Golang werden diese Methoden verwendet, um die Frist für Dateien festzulegen, aber manchmal können sie ungültig sein. Als Nächstes untersuchen wir mögliche Ursachen und bieten Lösungen an, um sicherzustellen, dass diese Methoden ordnungsgemäß funktionieren.

Frageninhalt

Ich verwende os.File.SetReadDeadlineos.File.ReadFull 的组合。但即使使用 SetReadDeadline,我设置的截止日期也被完全忽略,并且 ReadFull für immer blockieren. Warum das?

Zusätzliche Informationen: Ich feuere einige IOCTLS auf die Datei ab, daher wird os.File.Fd() benötigt, um den Dateideskriptor zu erhalten.

Lösung

tl; Arzt:

Verwenden Sie os.file.fd() 后,在文件上使用 syscall.setnonblock(fd.fd(), true)

Das liegt an read in 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
    }
}
Nach dem Login kopieren

Wenn die Datei auf den Blockierungsmodus eingestellt ist, wird das erste n, err := ignoringeintrio(syscall.read, fd.sysfd, p) 将永远阻塞。 waitread nur ausgeführt, wenn die Datei im nicht blockierenden Modus geöffnet wird. Aber ich habe die Datei im nicht blockierenden Modus geöffnet. Was ist also passiert?

Die Umsetzung von

os.file.fd() bricht es :

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)
}
Nach dem Login kopieren

fd() Stellen Sie Dateien immer auf Blockieren ein. Daher müssen wir den Vorgang rückgängig machen, bevor wir auf das Lesen der Abfrage warten. Deshalb:

Verwenden Sie os.file.fd() 后,在文件上使用 syscall.setnonblock(fd.fd(), true)

Das obige ist der detaillierte Inhalt vonGOLANG: Warum funktionieren SetDeadline/SetReadDeadline/SetWriteDeadline nicht für Dateien, wenn os.File.Fd() verwendet wird?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Quelle:stackoverflow.com
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage
Über uns Haftungsausschluss Sitemap
Chinesische PHP-Website:Online-PHP-Schulung für das Gemeinwohl,Helfen Sie PHP-Lernenden, sich schnell weiterzuentwickeln!