Rumah  >  Artikel  >  pembangunan bahagian belakang  >  GOLANG: Mengapa SetDeadline/SetReadDeadline/SetWriteDeadline tidak berfungsi untuk fail apabila menggunakan os.File.Fd()?

GOLANG: Mengapa SetDeadline/SetReadDeadline/SetWriteDeadline tidak berfungsi untuk fail apabila menggunakan os.File.Fd()?

PHPz
PHPzke hadapan
2024-02-09 08:30:211067semak imbas

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

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.

Kandungan soalan

Saya menggunakan os.File.SetReadDeadlineos.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.

Penyelesaian

tl;

Gunakan

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

Ini disebabkan oleh

readdalam 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
    }
}

Jika fail ditetapkan kepada mod menyekat,

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()

Gunakan

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!

Kenyataan:
Artikel ini dikembalikan pada:stackoverflow.com. Jika ada pelanggaran, sila hubungi admin@php.cn Padam