 |
 |
check if a process is alive
|
 |
|
 |
|
Senior User
Join Date: Jun 2002
Location: UK
Status:
Offline
|
|
I want to make an app that tells the user if one command line app is activated or not.
It's easy to make a one shot test: just throw `ps' into NSTask...
But the problem is that I want to make it `live' check. Meaning that if the process is started or killed my app updates the NSTextField accordingly.
Any ideas?
I don't like the idea of making my up run a test every x seconds as it will make everything very slow...
|
|
|
| |
|
|
|
 |
|
 |
|
Professional Poster
Join Date: Oct 1999
Location: :ИOITAↃO⅃
Status:
Offline
|
|
Is the process owned by the user, or by root?
If it's owned by the user, I'd do an occasional:
killall -0 processname
in an NSTask, and recover the exit code:
0 if the process is running
1 if it is not (or is owned by different user)
I don't see any way around "making my app run a test every x seconds" - if you want to test constantly, you'll have to test constantly.
If you have control over the command-line app (ie can change its source code) then an alternative is to have it write to a PID file on startup, and delete the file when it catches most stop signals.
|
|
|
| |
|
|
|
 |
|
 |
|
Senior User
Join Date: Jun 2002
Location: UK
Status:
Offline
|
|
doesn't really make me happy but thanks anyway 
|
|
|
| |
|
|
|
 |
|
 |
|
Mac Enthusiast
Join Date: Nov 2001
Status:
Offline
|
|
Mithras is right, you're going to have to poll using an NSTimer. To my knowledge, the kernel doesn't post any sort of notification when a process launches or terminates.
|
|
|
| |
|
|
|
 |
|
 |
|
Senior User
Join Date: Jun 2002
Location: UK
Status:
Offline
|
|
Originally posted by Ibson:
Mithras is right, you're going to have to poll using an NSTimer. To my knowledge, the kernel doesn't post any sort of notification when a process launches or terminates.
For "normal" apps you can use notification center, can't you, to listen for "terminate:"
Hmmm 
|
|
|
| |
|
|
|
 |
|
 |
|
Mac Enthusiast
Join Date: Nov 2001
Status:
Offline
|
|
Originally posted by VEGAN:
For "normal" apps you can use notification center, can't you, to listen for "terminate:"
Hmmm
No you can't. What terminate notification are you talking about?
|
|
|
| |
|
|
|
 |
|
 |
|
Senior User
Join Date: Jun 2002
Location: UK
Status:
Offline
|
|
Originally posted by Ibson:
No you can't. What terminate notification are you talking about?
NSWorkspaceDidLaunchApplicationNotification
NSWorkspaceDidTerminateApplicationNotification
|
|
|
| |
|
|
|
 |
|
 |
|
Mac Enthusiast
Join Date: Nov 2001
Status:
Offline
|
|
Originally posted by VEGAN:
NSWorkspaceDidLaunchApplicationNotification
NSWorkspaceDidTerminateApplicationNotification
I have a feeling these are only posted by -[NSWorkspace launchApplication:]. To quote from the docs:
- (BOOL)launchApplication:(NSString *)appName
...
Before this method begins, it posts an NSWorkspaceWillLaunchApplicationNotification to the NSWorkspace's notification center. When the operation is complete, it posts an NSWorkspaceDidLaunchApplicationNotification.
|
|
|
| |
|
|
|
 |
|
 |
|
Senior User
Join Date: Jun 2002
Location: UK
Status:
Offline
|
|
Originally posted by Ibson:
I have a feeling these are only posted by -[NSWorkspace launchApplication:]. To quote from the docs:
Nope, not as far as I know.
All apps launched from dock and finder will give a notification... of course, I may be mistaken
|
|
|
| |
|
|
|
 |
|
 |
|
Mac Enthusiast
Join Date: Nov 2001
Status:
Offline
|
|
Originally posted by VEGAN:
Nope, not as far as I know.
All apps launched from dock and finder will give a notification... of course, I may be mistaken
Sorry, no. You're right. I built a test app, and the notifications were posted. But this still doesn't solve your problem. Polling is the only way to go, I think.
|
|
|
| |
|
|
|
 |
|
 |
|
Senior User
Join Date: Nov 2000
Status:
Offline
|
|
if it's owned by the user, I'd do an occasional:
killall -0 processname
in an NSTask, and recover the exit code:
0 if the process is running
1 if it is not (or is owned by different user)
Why not...
Code:
BOOL processExistsForPID(int pid)
{
if (kill(pid, 0) == 0) return YES;
return NO;
}
...?
Then you'd just get the PID once* and avoid the overhead of using NSTask (/launching killall) every N secs. to see if something's running.
* ps -axo pid,command -c | grep "yourAppName" _or similar_
|
|
|
| |
|
|
|
 |
|
 |
|
Clinically Insane
Join Date: Oct 2001
Location: San Diego, CA, USA
Status:
Offline
|
|
Oiginally posted by IamBob:
Why not...
Code:
BOOL processExistsForPID(int pid)
{
if (kill(pid, 0) == 0) return YES;
return NO;
}
...?
Then you'd just get the PID once* and avoid the overhead of using NSTask (/launching killall) every N secs. to see if something's running.
That would only tell you if the program was quit. If the program wasn't running at the time you did the check, or has since been restarted, you won't know its PID.
|
|
Chuck
___
"Instead of either 'multi-talented' or 'multitalented' use 'bisexual'."
|
| |
|
|
|
 |
|
 |
|
Grizzled Veteran
Join Date: Sep 2000
Location: Springfield, MA
Status:
Offline
|
|
Originally posted by Chuckit:
That would only tell you if the program was quit. If the program wasn't running at the time you did the check, or has since been restarted, you won't know its PID.
Right, but if the program wasn't running at the time you did the check, then why would you be trying to find out if it has since quit?
If you don't know the PID, then instead of checking if it has quit, run the code to try and get its PID. Then, once you know the PID, you run the code to see if it is still running.
|
|
We hope your rules and wisdom choke you / Now we are one in everlasting peace
-- Radiohead, Exit Music (for a film)
|
| |
|
|
|
 |
|
 |
|
Senior User
Join Date: Nov 2000
Status:
Offline
|
|
That would only tell you if the program was quit. If the program wasn't running at the time you did the check, or has since been restarted, you won't know its PID.
Ok, I didn't think my original solution all the way through. Thanks for pointing that out - dammit.
How 'bout this...
Use killall to see if the app is running. If not, you can either start it or use killall on a timer to tell you (roughly) when it's launched*. Once the app is running, grab the pid and use processExistsForPID() to see when the application quits/dies**. wash, rinse, repeat..
There, problem solved (I hope).
* killall would make sense here if you didn't just [re-]launch the app because it's all about the time it takes to run killall vs. ps + grep at that point.
** Once you know the app is running there's no point in running killall. You can avoid the extra overhead by using ps to get its pid (once per run-session) and kill() to see if it's running.
Someone probably knows a better way than that, I bet. Hell, you could go as far (or farther?) as using sysctl (man 3 sysctl) to gather the process table data yourself for more control and possibly faster execution. I offered up just what I thought was wanted - a faster, yet still easy, way to do this.
|
|
|
| |
|
|
|
 |
 |
|
 |
|
|
|
|
|

|
|
 |
Forum Rules
|
 |
 |
|
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
|
HTML code is Off
|
|
|
|
|
|
 |
 |
 |
 |
|
 |
|