在 Go 中,SyscallConn() 什么时候对常规 *os.File 有用?

问题描述 投票:0回答:1

我正在阅读一些 Go 代码(来自 https://github.com/KarpelesLab/reflink),它使用

SyscallConn()
(在
*os.File
上定义的函数):

// reflinkInternal performs the actual reflink action without worrying about fallback
func reflinkInternal(d, s *os.File) error {
    ss, err := s.SyscallConn()
    if err != nil {
        return err
    }
    sd, err := d.SyscallConn()
    if err != nil {
        return err
    }
    var err2, err3 error
    err = sd.Control(func(dfd uintptr) {
        err2 = ss.Control(func(sfd uintptr) {
            // int ioctl(int dest_fd, FICLONE, int src_fd);
            err3 = unix.IoctlFileClone(int(dfd), int(sfd))
        })
    })
    if err != nil {
        // sd.Control failed
        return err
    }
    if err2 != nil {
        // ss.Control failed
        return err2
    }
    if err3 != nil && errors.Is(err3, unix.ENOTSUP) {
        return ErrReflinkFailed
    }
    // err3 is ioctl() response
    return err3
}

在此示例中,使用这些

Control()
函数而不是直接使用
d.Fd()
s.Fd()
有什么优势吗?更一般地说, func
func (*os.File) SyscallConn() (syscall.RawConn, error)
有什么用?

go file-io
1个回答
0
投票

file.Fd()
返回一个文件描述符,并且它使文件描述符在阻塞模式下运行(占用一个线程来进行阻塞操作)。
SyscallConn
不这样做。事实上,它是专门为了获取文件描述符而不使其阻塞而创建的。请参阅本期了解更多信息

© www.soinside.com 2019 - 2024. All rights reserved.