守护(daemon)进程即在后台运行的进程,网上有很多介绍守护进程的文章,这里不再赘述,直接上代码。
- static void _daemon_prep(int stderr_log)
- {
- /* Avoid keeping any directory in use. */
- chdir("/");
- /* Reset process session id. */
- setsid();
- /* If you want to log in console. */
- if (stderr_log)
- return;
- /*
- * Close inherited file descriptors to avoid
- * keeping unnecessary references.
- */
- close(0);
- close(1);
- close(2);
- /*
- * Redirect std{in,out,err}, just in case.
- */
- open("/dev/null", O_RDWR);
- dup(0);
- dup(0);
- }
- static int _daemonize()
- {
- int pid = fork();
- if (pid != 0) {
- // parent, exit
- if (pid == -1) {
- //cerr << "daemonize failed!" << endl;
- return -1;
- }
- exit(0);
- } else {
- // child, continue
- //cout << "daemonnize success!" << endl;
- _daemon_prep(0);
- return 0;
- }
- }
在你的 main 函数中调用 _daemonize 方法即可使你的进程变成守护进程。如以下示例:
- int main()
- {
- _daemonize();
- while(1) {
- cout << "hello, world" << endl;
- sleep(1);
- }
- exit(0);
- }
以上"hello, world"程序会在后台运行,因在_daemon_prep函数中将标准输入输出重定位到了/dev/null,故你在终端看不到任何输出。如你想在终端看到输出,可在调用_daemon_prep时传入参数1。如你想把标准输出、错误输出重定位到文件方便后续查看,可修改代码如下:
- /*
- * Redirect std{in,out,err}, just in case.
- */
- open("/dev/null", O_RDWR); // stdin
- if (open("/var/log/yourapp.log", O_RDWR | O_CREAT | O_TRUNC) < 0 ) {
- cerr << "open error!" << endl;
- dup(0); // stdout
- dup(0); // stderr
- } else {
- dup(1); // redirect stderr to the file same as stdout
- }