问题
What I know:
When a process is running I can press "CTRL + Z" and suspend it. The with bg
and fg
commands I can either run it in "background" or "foreground" mode.
What I'm aksing:
Is there a way to suspend a process, send it to run in background or foreground in C?
Edit: I have the process id. I want to send that process to the background for example.
回答1:
You can suspend it with kill(pid, SIGSTOP), but making it foreground or background is a function of the shell that ran it, since what it actually affects is whether the shell displays a prompt (and accepts a new command) immediately or waits until the job exits. Unless the shell provides an RPC interface (like DBus), there's no clean way to change the waiting/not waiting flag.
回答2:
A Linux process can usually be suspended by sending it the SIGSTOP signal or resumed by sending it the SIGCONT signal. In C,
#include <signal.h>
kill(pid, SIGSTOP);
kill(pid, SIGCONT);
A process can suspend itself using pause()
.
"Foreground" and "background" modes are not properties of the process. They are properties of how the parent shell process interacts with them: In fg mode, input to the shell is passed to the child process, and the shell waits for the child process to exit. In bg mode, the shell takes input itself, and runs parallel to the child process.
回答3:
You cannot. bg
and fg
are shell commands, and you cannot invoke a command within an arbitrary shell from C.
回答4:
The usual way is to fork off a child process, and exit the parent. See this for a simple example.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#define EXIT_SUCCESS 0
#define EXIT_FAILURE 1
static void daemonize(void)
{
pid_t pid, sid;
/* already a daemon */
if ( getppid() == 1 ) return;
/* Fork off the parent process */
pid = fork();
if (pid < 0)
{
exit(EXIT_FAILURE);
}
/* If we got a good PID, then we can exit the parent process. */
if (pid > 0)
{
exit(EXIT_SUCCESS);
}
/* At this point we are executing as the child process */
/* Change the file mode mask */
umask(0);
/* Create a new SID for the child process */
sid = setsid();
if (sid < 0)
{
exit(EXIT_FAILURE);
}
/* Change the current working directory. This prevents the current
directory from being locked; hence not being able to remove it. */
if ((chdir("/")) < 0)
{
exit(EXIT_FAILURE);
}
/* Redirect standard files to /dev/null */
freopen( "/dev/null", "r", stdin);
freopen( "/dev/null", "w", stdout);
freopen( "/dev/null", "w", stderr);
}
int main( int argc, char *argv[] )
{
daemonize();
/* Now we are a daemon -- do the work for which we were paid */
return 0;
}
来源:https://stackoverflow.com/questions/6574370/job-control-in-linux-with-c