Many programs use lock files to terminate if the the same program is alreadly running.
This is better than just checking all running processes for one with the same command because that does not allow the for programs to lock only in some states.
But there is a better methods, file locks. File locks (flock) allows shared locks and exclusive locks, as well as waiting for the locks to unlock. If you apply a shared lock on a file, it will wait (or fail if using non-blocking flock) for a exclusive lock to unlock if there is one. If you are apply an exclusive lock on file, it will wait (or fail) for all other locks to unlock. So you use shared lock when you are entering a reading state, and exclusive lock if you are entering a write state.
But wait there is more. File locks are handled by the filesystem and they unlock locks that were applied by a process that has exited. So if you use file locks and the program crashes, the user does not have to manually remove a lock file.
So in summation: file locks (flock) are fail safe and supports both shared locks and exclusive locks.
But keep in mind that flock locks are only honour by flock, you can still open a file if you just dot wrap those instructions around flock instructions.
Flock is supported by C, shell script languages, Python, and probably many more languages.