Determine what the calling program is

Cameron Simpson cs at cskk.id.au
Sun Apr 18 18:54:06 EDT 2021


On 18Apr2021 07:46, Jason Friedman <jsf80238 at gmail.com> wrote:
>I should state at the start that I have a solution to my problem. I am
>writing to see if there is a better solution.
[...]
>I have written a piece of code to detect if more than 1 instance of my
>program is running, and I put this code into a separate module (support.py)
>so that other programs can use it.
[... sniff the process table ...]

Sniffing ps has always seemed unreliable to me.

It is usually better to use some kind of filesystem based lock, named to 
represent your task.

My personal preference is lock directories. Shell version goes like 
this:

    if mkdir /my/lock/directory/name-of-task
    then
       .. do task ..
       rmdir /my/lock/directory/name-of-task
    else
      echo "lock /my/lock/directory/name-of-task already taken"
    fi

Simple, reliable, even works over NFS if you care.

In Python this looks like (sketch, untested):

    try:
        os.mkdir('/my/lock/directory/name-of-task')
    except FileExistsError:
        error("lock taken")
    else:
        .. do task ..
        os.rmdir('/my/lock/directory/name-of-task')

You can even put a pid file in there for added richness, identifying the 
pid of the competing process. Or whatever.

You can also make O_EXCL or O_CREAT/unwriteable files for locks:

    # untested, check spelling etc
    os.open('/my/lock/directory/name-of-task', O_CREAT|O_WRONLY, 0o000)

On a UNIX system this opens an unwriteable file for write (you get to 
open it for write because it is new, but its permissions are 
unwriteable, preventing anyone else from opening it for write).

These (mkdir, os.open) have the benefits of making a nice direct 
filesystem object rather than hoping to see your task in ps. And ps 
sniffing is racey, in addition to its other issues.

Cheers,
Cameron Simpson <cs at cskk.id.au>


More information about the Python-list mailing list