我有一个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
正在工作,但是从另一个包而不是主包中调用它,但是当我尝试从主包中放入锁时会抛出相同的错误。请帮助我找出我在这里做错了什么。
答案 0 :(得分:1)
创建锁定时发生错误时,lockProgram
将为nil
。这将导致对lockProgram.Close()
的后续(延迟)调用失败。
请注意,当您感到恐慌时(例如在CheckForError
函数中),仍会执行延迟方法调用。这在this blog article(强调我的)中有详细解释:
恐慌是一种内置功能,可以阻止普通的控制流并开始恐慌。当函数F调用恐慌时,F的执行停止, F中的任何延迟函数正常执行,然后F返回其调用者。对于呼叫者,F然后表现得像是对恐慌的呼唤。进程继续向上移动,直到当前goroutine中的所有函数都返回,此时程序崩溃。
解决方案:首先检查错误,然后推迟Close()
调用:
lockProgram, err := os.Create("/var/.daemon.lock")
CheckForError(err)
defer lockProgram.Close()