Golang flock文件锁定引发恐慌:运行时错误:无效内存地址或无指针取消引用



我有一个go程序可以修改我的配置文件。我试图从main()函数中创建一个文件锁,但它抛出了一个panic: runtime error: invalid memory address or nil pointer dereference错误。如果没有锁,程序运行正常。抛出异常的代码是

lockProgram, err := os.Create("/var/.daemon.lock")
defer lockProgram.Close()
CheckForError(err)
GetLock(lockProgram, syscall.LOCK_EX)
defer UngetLock(lockProgram)

//这是在一个单独的包装中

func CheckForError(e error) {
    if e != nil {
        Error.Println(e)
        panic(e)
    }
}
func GetLock(file *os.File, locktype int )  {
    fmt.Println("Acquiring lock on ", file.Name())
    syscall.Flock(int(file.Fd()), locktype)
    fmt.Println("Acquired filelock on ", file.Name())
}
func UngetLock(file *os.File)  {
    syscall.Flock(int(file.Fd()), syscall.LOCK_UN);
}

当我在配置文件上调用这个flock时,它也在工作,但来自不同的包,而不是主包,但当我试图从主包中锁定时,它会抛出相同的错误。请帮我找出我在这里做错了什么。

创建锁时发生错误时,lockProgram将为nil。这将导致对lockProgram.Close()的后续(延迟)调用失败。

请注意,当您感到恐慌时(如在CheckForError函数中),延迟的方法调用仍将执行。这在这篇博客文章中有详细的解释(重点是我的):

恐慌是一个内置的功能,它可以停止普通的控制流并开始恐慌。当函数F调用panic时,F的执行将停止,F中的任何延迟函数都将正常执行,然后F返回其调用方。对呼叫者来说,F的行为就像是在呼唤恐慌。该进程继续向上堆栈,直到当前goroutine中的所有函数都返回,此时程序崩溃。

解决方案:首先检查错误,然后推迟Close()调用:

lockProgram, err := os.Create("/var/.daemon.lock")
CheckForError(err)
defer lockProgram.Close()

最新更新