2

我有一个修改我的配置文件的 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有效,但来自不同的包,而不是主包,但是当我尝试从主包中放置锁时会抛出相同的错误。请帮助我找出我在这里做错了什么。

4

1 回答 1

1

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

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

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

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

lockProgram, err := os.Create("/var/.daemon.lock")
CheckForError(err)
defer lockProgram.Close()
于 2016-01-10T20:39:57.847 回答