Richard Bucker

GoLang implementation of 'man 1 flock'

Posted at — Jan 11, 2015

Linux has a utility called flock. It’s pretty handy because it’ll prevent the current program from running a second time. This is particularly useful when a cronjob’s runtime is longer than it’s interval. The described flock util creates a file and then sets it’s lock.  If a second instance is started then the flock function will cause the second to fail so long as you are watching the response values.
package main

import (
“fmt”
“os”
“syscall”
“time”
)

func main() {
file, err := os.OpenFile(“test.dat”, os.O_CREATE+os.O_APPEND, 0666)
if err != nil {
fmt.Printf(“%v\n”, err)
}
fd := file.Fd()
fmt.Printf(“%x\n”, fd)
err = syscall.Flock(int(fd), syscall.LOCK_EX+syscall.LOCK_NB)
if err != nil {
fmt.Printf(“%v\n”, err)
}
fmt.Println(“sleeping”)
time.Sleep(time.Duration(15) * time.Second)
}


A little more needs to be done to this code like pull the command from the CLI and a number of other params (see the link). But at least it is possible. Note that the Flock() take the Fd() from the file, however, this value needs to be cast from uintptr to int and back to uintptr. For the timbering this is ok but it may not survive the future. There is also a challenge that int can be < 0.