package utils
import (
"errors"
"golang.org/x/sys/unix"
"os"
)
const lockFile = "/tmp/.test.lock"
var lockFileHandle *os.File
// IsRunning checks if the program is already running by using a lock file.
// Returns true if it is locked (i.e., the program is already running), false otherwise.
func IsRunning() (isRunning bool, err error) {
lockFileHandle, err = os.OpenFile(lockFile, os.O_CREATE|os.O_RDWR, 0666)
if err != nil {
return false, err
}
if err = unix.Flock(int(lockFileHandle.Fd()), unix.LOCK_EX|unix.LOCK_NB); err != nil {
if errors.Is(err, unix.EWOULDBLOCK) {
return true, nil
}
return false, err
}
return false, nil
}
// Unlock unlocks the lock file and removes it.
// You should always defer this function after calling IsRunning.
func Unlock() error {
if lockFileHandle == nil {
return nil
}
defer lockFileHandle.Close()
if err := unix.Flock(int(lockFileHandle.Fd()), unix.LOCK_UN); err != nil {
return err
}
return os.Remove(lockFile)
}
Last active
January 30, 2025 11:02
-
-
Save aamaanaa/bec0b17e6f2909527792c329692db322 to your computer and use it in GitHub Desktop.
Golang Linux & Mac Mutex | Lock file | Only allow one instance of your go app on unix based systems (mac os, Linux)
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Simple utils package to only allow a single instance by using a exclusive lock file of your golang app on a unix based system. This works for both Mac and Linux, altough i did not tested on mac since i dont own one. code tested on Fedora Linux.
You must not call os.Exit in the
running == true
block. This would not run the deffered statementutils.Unlock();
wich releases the lockfile and deletes it.a dot before the lock files makes it by default a hidden file in the
/tmp
dir, wich is world writable by any program.It requires the
"golang.org/x/sys/unix"
, a package for low level system calls for unix based systems.Get it with:
Example usage: