Maison > développement back-end > Golang > le corps du texte

GOLANG : Pourquoi SetDeadline/SetReadDeadline/SetWriteDeadline ne fonctionne-t-il pas pour les fichiers lors de l'utilisation de os.File.Fd() ?

PHPz
Libérer: 2024-02-09 08:30:21
avant
1067 Les gens l'ont consulté

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

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.

Contenu des questions

J'utilise os.File.SetReadDeadlineos.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.

Solution

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
    }
}
Copier après la connexion

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é ?

La mise en œuvre de

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)
}
Copier après la connexion

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!

source:stackoverflow.com
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal
À propos de nous Clause de non-responsabilité Sitemap
Site Web PHP chinois:Formation PHP en ligne sur le bien-être public,Aidez les apprenants PHP à grandir rapidement!