daemon 函数用于脱离控制台、转入后台运行。相比于通过 nohup 启动进程,优点是无需额外修改启动命令。但是,daemon 的调用位置却有讲究。如果非 daemon 进程测试一切 OK,但调用 daemon 后却出现各种问题,很可能是你用错了!
daemon 的原理是: fork 并在子进程中继续运行,父进程 exit。陷阱的根源就在于进程的切换。
1. 是否依赖进程号?
进程切换导致 PID 发生改变,如果函数逻辑与进程号有关,那么就得注意了。
一个例子是 netlink。
struct sockaddr_nl local;
memset(&local, 0, sizeof(local));
local.nl_family = AF_NETLINK;
local.nl.pid = getpid();
local.nl_groups = 0;
........
daemon(0, 0);
如果代码类似这样,那么恭喜你,中奖了。
2. 父进程中是否创建了线程?
子进程不会继承父进程中的线程,所以,如果子进程仍然需要这些线程,那么 daemon 调用必须在线程创建之前。
if (0 != pthread_create(&id, NULL, alarm_dns, (void *)argv[PARA_IP_LIDS]))
return printf("dns thread create error\n");
........
(void)daemon(0, 0);
如果代码形如上,那么恭喜你,再次中奖了!