我想在Unix中的远程机器上运行程序作为守护进程.我有rsh连接,我希望程序在断开连接后运行.
假设我有两个程序:util.cpp和forker.cpp.
util.cpp是一些实用程序,为了我们的目的,让它只是无限的根.
util.cpp
int main() {
while (true) {};
return 0;
}
forker.cpp需要一些程序并通过fork()和execve()在separe进程中运行它:
forker.cpp
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc, char** argv) {
if (argc != 2) {
printf("./a.out <program_to_fork>\n");
exit(1);
}
pid_t pid;
if ((pid = fork()) < 0) {
perror("fork error.");
exit(1);
} else if (!pid) {
// Child.
if (execve(argv[1], &(argv[1]), NULL) == -1) {
perror("execve error.");
exit(1);
}
} else {
// Parent: do nothing.
}
return 0;
}
如果我跑:
./forker util
forker很快完成,bash’没有暂停’,而util正在作为守护进程运行.
但如果我跑:
scp forker remote_server://some_path/
scp program remote_server://some_path/
rsh remote_server 'cd /some_path; ./forker program'
然后它是完全相同的(即在remote_sever forker快速完成,util正在运行)但我在本地机器上的bash暂停了.
它正在等待util停止(我检查了它.如果util.cpp返回比它还可以.),但我不明白为什么?!
有两个问题:
1) Why is it paused when I run it through rsh?
我确信我选择了一些愚蠢的方式来运行守护进程.所以
2) How to run some program as daemon in C/C++ in unix-like platforms.
TNX!
最佳答案
1) Why is it paused when I run it through rsh?
分叉进程时,子进程有自己的父文件描述符副本.每个子文件描述符引用与父对应文件描述符相同的打开文件描述.调用fork()之后,在调用execve()之前,不会关闭子进程中的标准流(stdin,stdout,stderr),因此它们仍然连接到rsh.可能的情况是,只要远程服务器上的任何进程持有对这些流的引用,rsh就不会返回.您可以尝试在调用execve()之前使用fclose()
关闭标准流,或者在执行forker程序时重定向它们(即./forker program> / dev / null 2> / dev / null< / dev / null) .
2) How to run some program as daemon in C/C++ in unix-like platforms.
根据wikipedia,nohup
最常用于在后台运行命令作为守护进程.您还可以参考此网站上的几个daemon related questions获取信息.
从wikipedia开始:
nohup is a POSIX command to ignore the HUP (hangup) signal, enabling the command to keep running after the user who issues the command has logged out. The HUP (hangup) signal is by convention the way a terminal warns depending processes of logout.
如果您的程序将始终作为守护程序运行,您可以查看从程序中调用daemon()的可能性.守护进程()方便功能存在于某些UNIX系统中.
The daemon() function is for programs wishing to detach themselves from the controlling terminal and run in the background as system daemons.
如果您不存在此函数,或者如果您的程序没有作为守护程序运行,那么您的forker程序也可以修改为“daemonize”您的其他程序.
无需对代码进行任何更改,您可以尝试以下内容:
rsh remote_server’cd / some_path; nohup ./forker program> program.out 2> program.err< / dev / null&’