Is A Process Running?

Just curious--is there some way in Racket to check if a given binary is running or not?

(subprocess? ) doesn't seem to find the process I'm looking for. I mean I check by process-id and I get false and I check by name and I also get false. But I am trying it on Windows so I realize that might be part of the problem.

Since no one has answered, let me help by offering a probably-mediocre answer that nudges someone else to improve it for you :smile:

  • I'm not aware that Racket offers a general, portable way to do this.

  • Do you care about a process that you wrote and can modify, and you want to limit it to running once? If so, one idea: Use a file as a flag.

    • If foo.lock doesn't exist, foo creates it and proceeds running.
    • If foo.lock exists, foo will exit rather than continue to run.
    • Probably use a plumber or exit-handler to delete reliably.
    • Probably locate the file in temp dir.

    Something like that?

    (I think .lock is a convention but I don't recall where I've seen that.)

2 Likes

Thanks Greg. I was hoping I was missing some simple Racket library call but if there's no easy way to do it then I can fudge something.

I think the .lock file is a good suggestion.

subprocess? is a predicate on Racket values (mostly for those returned by subprocess) and is not like the (Unixy) pgrep <name>.

RE the lockfile, I think many package managers do something similar. I actually think there's system support for that via https://docs.racket-lang.org/reference/Filesystem.html#%28def._%28%28lib._racket%2Ffile..rkt%29._call-with-file-lock%2Ftimeout%29%29. If you use the same protocol in your binary, that might help.

Could you solve the problem by invoking an external command?

I might be able to do so. It's not worth that much trouble honestly. :slightly_smiling_face: As you may recall I've been hacking away at shell scripts in Racket and while I don't know for sure that it would cause a problem I was simply attempting to avoid spawning the same binary twice.

Since it's something I'm building solely for myself if I accidentally spawn the binary twice, it's not a catastrophe. :smiley:

If it's a process that you started from Racket:

  1. using subprocess, you can use:
    • subprocess-status to poll;
    • subprocess-wait to block (potentially in a fresh thread); or
    • sync on the subprocess? value, in the general case;
  2. using process* and friends, you can call the returned control procedure:
    • with 'status to poll;
    • with 'wait to block; or
    • with 'wait in a fresh thread, to simulate sync on a subprocess? by using thread-dead-evt; or
  3. using system* and friends, wait on a dedicated thread.

If you're interested in some arbitrary process, then you probably need to call a system API via the FFI, invoke a helper command, or use a protocol like @greghendershott and @benknoble described.

If you're interested in whether another instance of your application process is already running, e.g. to do something like “single instance” support for desktop applications, then you probably want some IPC mechanism, too, so maybe you use racket/unix-socket, or maybe you use your ability (or not) to listen on some application-specific TCP port as a flag.

1 Like