我想在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!
答案 0 :(得分:2)
1)当我通过rsh运行时为什么会暂停?
当您分叉进程时,子进程有自己的父文件描述符副本。每个子文件描述符引用与父对应文件描述符相同的打开文件描述。在致电fork()
之前,您没有关闭子流程中的标准流(stdin
,stdout
,stderr
),因此他们是execve()
仍然连接到rsh。可能的情况是,只要远程服务器上的任何进程持有对这些流的引用,rsh就不会返回。在调用execve()
之前,您可以尝试使用fclose()
关闭标准流,或在执行forker程序时重定向它们(例如./forker program >/dev/null 2>/dev/null </dev/null
)。
2)如何在类似unix的平台中将一些程序作为守护进程在C / C ++中运行。
根据wikipedia,nohup
最常用于在后台运行命令作为守护进程。此网站上还有几个daemon related questions,您可以参考这些信息。
来自wikipedia:
nohup是一个POSIX命令,用于忽略HUP(挂断)信号,使命令在发出命令的用户注销后继续运行。按照惯例,HUP(挂断)信号是终端根据注销过程发出警告的方式。
如果您的程序将始终作为守护程序运行,您可以查看从程序中调用daemon()
的可能性。某些UNIX系统中存在daemon()
便利函数。
daemon()函数适用于希望从控制终端分离并在后台作为系统守护进程运行的程序。
如果您不存在此函数,或者如果您的程序未作为守护程序运行,则您的forker程序也可以修改为“守护”您的其他程序。
不对代码进行任何更改,您可以尝试以下内容:
rsh remote_server 'cd /some_path; nohup ./forker program >program.out 2>program.err </dev/null &'