Linux进程实践(5) --守护进程
概述
守护进程是在需要在后台长期运行不受终端控制的进程,通常情况下守护进程在系统启动时自动运行,在服务器关闭的时候自动关闭;守护进程的名称通常以d结尾,比如sshd、xinetd、crond、atd等。
守护进程编程规则
调用umask将文件模式创建屏蔽字设置为一个已知值(通常是0)
调用fork(),创建新进程,它会是将来的守护进程
然后使父进程exit,保证子进程不是进程组组长
调用setsid创建新的会话
会话:是一个或者多个进程组的集合,通常一个会话开始与用户登录,终止于用户退出。在此期间,该用户运行的所有进程都属于这个会话期。
将进程的当前目录改为根目录 (如果把当前目录作为守护进程的目录,当前目录不能被卸载,它作为守护进程的工作目录了。)
关闭不再需要的文件描述符
将标准输入、标准输出、标准错误重定向到/dev/null
setsid
pid_t setsid(void);
setsid() creates a new session if the calling process is not a process group leader. The calling process is the leader of the new session, the process group leader of the new process group, and has no controlling terminal. The process group ID and session ID of the calling process are set to the PID of the calling process. The calling process will be the only process in this new process group and in this new session.
/*当调用进程不是一个进程组的组长时,Setsid创建一个新的会话;调用者进程会是这个会话期唯一的一个进程,且是该进程组的组长;调用者进程id是组id,也是会话期的id。不能用进程组组长去调用setsid函数*/
//示例:
int main()
{
pid_t pid = fork();
if (pid == -1)
err_exit("fork error");
else if (pid != 0)
exit(EXIT_SUCCESS);
// //查看下面这一部分代码在注释的前后有什么变化
// pid_t id = setsid();
// if (id == -1)
// err_exit("setsid error");
// else
// cout << "new session id = " << id << endl;
cout << "getpid = " << getpid() << endl;
cout << "getpgid = " << getpgid(getpid()) << endl;
return 0;
}
RETURN VALUE
On success, the (new) session ID of the calling process is returned. On error, (pid_t) -1 is returned, and errno is set to indicate the error.
Linux中的守护进程API
int daemon(int nochdir, int noclose);
参数:
nochdir:=0将当前目录更改至“/”
noclose:=0将标准输入、标准输出、标准错误重定向至“/dev/null”
DESCRIPTION
The daemon() function is for programs wishing to detach themselves from the controlling terminal and run in the background as system daemons. If nochdir is zero, daemon() changes the calling process's current working directory to the root directory ("/"); otherwise, the current working directory is left unchanged. If noclose is zero, daemon() redirects standard input, standard output and standard error to /dev/null; otherwise, no changes are made to these file descriptors.
//示例:自己动手写daemon函数(一个比较简单的示例)
bool myDaemon(bool nochdir, bool noclose)
{
umask(0);
pid_t pid = fork();
if (pid == -1)
err_exit("fork error");
else if (pid != 0) //parent
exit(0);
setsid();
if (nochdir == 0)
chdir("/");
if (noclose == 0)
{
int i;
for (i=0; i < 3; ++i)
close(i);
open("/dev/null", O_RDWR); //相当于把0号文件描述符指向/dev/null
dup(0); //把0号文件描述符 赋值给空闲的文件描述符 1
dup(0); //把0号文件描述符 赋值给空闲的文件描述符 2
}
return true;
}
//测试
int main(int argc, char *argv[])
{
myDaemon(0, 0); //0表示做出改变(当前目录,文件描述符),1表示不改变
printf("test ...\n");
while (true)
{
sleep(1);
}
return 0;
}
//一个比较经典和完善的实例;来自《APUE》
#include "apue.h"
#include <syslog.h>
#include <fcntl.h>
#include <sys/resource.h>
bool myDaemon(const char *cmd);
int main(int argc, char *argv[])
{
myDaemon("xiaofang");
while (true)
{
sleep(1);
}
return 0;
}
bool myDaemon(const char *cmd)
{
umask(0);
//Get maximum number of file descriptors.
rlimit rlt;
if (getrlimit(RLIMIT_NOFILE,&rlt) < 0)
{
err_quit("%s: can't get file limit",cmd);
}
//Become a session leader to lose controlling TTY.
pid_t pid = fork();
if (pid == -1)
{
err_quit("%s: can't fork",cmd);
}
if (pid != 0) //parent
{
exit(0);
}
setsid();
//Ensure future opens won't allocate controlling TTYs.
struct sigaction sa;
sa.sa_handler = SIG_IGN;
sigemptyset(&sa.sa_mask);
sa.sa_flags = 0;
if (sigaction(SIGHUP,&sa,NULL) < 0)
{
err_quit("%s can't ignore SIGHUP",cmd);
}
if ((pid = fork()) < 0)
{
err_quit("%s: can't fork",cmd);
}
else if (pid != 0) //Second Parent
{
exit(EXIT_SUCCESS);
}
//change the current working directory to the root
if (chdir("/") < 0)
{
err_quit("%s: can't change directory to /",cmd);
}
//close all open file description
if (rlt.rlim_max == RLIM_INFINITY)
{
rlt.rlim_max = 1024;
}
for (unsigned int i = 0; i < rlt.rlim_max; ++i)
{
close(i);
}
//Attach file descriptors 0, 1, and 2 to /dev/null.
int fd0 = open("/dev/null",O_RDWR);
int fd1 = dup(0);
int fd2 = dup(0);
//Initialize the log file.
openlog(cmd,LOG_CONS,LOG_DAEMON);
if (fd0 != 0 || fd1 != 0 || fd2 != 0)
{
syslog(LOG_ERR,"unexpected file descriptors %d %d %d",
fd0,fd1,fd2);
exit(EXIT_FAILURE);
}
return true;
}
Linux进程实践(5) --守护进程的更多相关文章
- Linux编程之《守护进程》
Intro ----- 守护进程,也就是通常说的Daemon进程,是Linux中的后台服务进程.它是一个生存期较长的进程,通常独立于控制终端并且周期性地执行某种任务或等待处理某些发生的事件.守护进程常 ...
- Linux 下Qt实现守护进程实例(转)
原文地址:Linux守护进程的编程方法(含实例) 作者:lingdxuyan 参考文献 Linux信号列表(zz) Linux 守护进程的编程方法 linux上编写守护进程的例程 Linux下后台守 ...
- Linux进程托管与守护进程设置
引言 在上一篇<Linux启动之旅>中,我们了解了Linux启动过程,在该过程的最后一步,init进程拉起/etc/init.d/rcN.d/目录下指定的守护进程(daemon).假若自定 ...
- Linux下一个简单守护进程的实现 (Daemon)
在Linux/UNIX系统引导的时候会开启很多服务,这些服务称为守护进程(也叫Daemon进程).守护进程是脱离于控制终端并且在后台周期性地执行某种任务或等待处理某些事件的进程,脱离终端是为了避免进程 ...
- 一只简单的网络爬虫(基于linux C/C++)————守护进程
守护进程,也就是通常说的Daemon进程,是Linux中的后台服务进程.它是一个生存期较长的进程,通常独立于控制终端并且周期性地执行某种任务或等待处理某些发生的事件.守护进程常常在系统引导装入时启动, ...
- (七) 一起学 Unix 环境高级编程(APUE) 之 进程关系 和 守护进程
. . . . . 目录 (一) 一起学 Unix 环境高级编程 (APUE) 之 标准IO (二) 一起学 Unix 环境高级编程 (APUE) 之 文件 IO (三) 一起学 Unix 环境高级编 ...
- python 进程锁 生产者消费者模型 队列 (进程其他方法,守护进程,数据共享,进程隔离验证)
#######################总结######### 主要理解 锁 生产者消费者模型 解耦用的 队列 共享资源的时候 是不安全的 所以用到后面的锁 守护进程:p.daem ...
- python开发 *进程数据隔离.守护进程,进程同步工具 * 180725
进程数据隔离.守护进程,进程同步工具 一.进程之间的数据隔离: from multiprocessing import Process n=100 #主程序中变量n= def func(): glob ...
- Python 之并发编程之进程中(守护进程(daemon)、锁(Lock)、Semaphore(信号量))
五:守护进程 正常情况下,主进程默认等待子进程调用结束之后再结束守护进程在主进程所有代码执行完毕之后,自动终止kill -9 进程号 杀死进程.守护进程的语法:进程对象.daemon = True设置 ...
随机推荐
- Hibernate异常之Integer转float(自动类型转换错误)
错误代码: java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.Float at org.hiber ...
- Ubuntu Intel显卡驱动安装 (Ubuntu 14.04--Ubuntu 16.10 + Intel® Graphics Update Tool)
最近使用在使用Ubuntu时,发现大部分情况下,不安装显卡驱动,使用默认驱动,都是没有问题的,但对于一些比较奇特配置的电脑,如下所示,如果使用默认驱动,会时常莫名其妙死机crash,尤其是在使用Ope ...
- ROS机器人程序设计(原书第2版)学习镜像分享及使用说明
ROS机器人程序设计(原书第2版)学习镜像分享及使用说明 系统用于ROS爱好者学习交流,也可用于其他用途,并不局限于ROS. 这款镜像文件是基于一年前的Ubuntu ROS Arduino Gazeb ...
- 查看4k对齐,激活.net framework 3.5
查看是否4k对齐 Win+R,打开运行窗口,在窗口中输入“msinfo32",组件”--“存储”--“磁盘”.然后可以在右边栏看到“分区起始偏移”,我们图例中有2个数值,分别是:32256字 ...
- java解决Url带中文参数乱码问题
首先打开Tomcat安装目录,打开conf文件,打开server.xml,找到这段代码: <Connector port="8080" protocol="HTTP ...
- /proc/stat 详解
在Linux系统中,可以用/proc/stat文件来计算cpu的利用率.这个文件包含了所有CPU活动的信息,该文件中的所有值都是从系统启动开始累计到当前时刻. cat /proc/stat cpu 6 ...
- Struts1基础、使用Struts实现登录、使用Struts HTML标签简化开发
Struts 1基础 为什么重拾Struts 1 曾经是最主流的MVC框架 市场份额依然很大 很多遗留系统中依旧使用 维护和升级都需要熟悉Struts 1 与Struts 2相比 编码.配置繁琐 侵入 ...
- Gazebo機器人仿真學習探索筆記(二)基本使用說明
在完成Gazebo7安裝後,需要熟悉Gazebo,方便之後使用. 部分源代碼可以參考:https://bitbucket.org/osrf/gazebo/src/ 如果還沒有安裝請參考之前內容完成安裝 ...
- win8如何共享文件夹
最近小编接手了市委组织部考核项目,各种文档.ER图.原型图,组员之间需要拷来拷去,很不方便,通过飞信,QQ传输吧,文件太大,网络太慢,所以还是不行,于是小编就想起来要共享,以前也映射过别人的共享,觉得 ...
- 详解EBS接口开发之库事务处理带提前发运通知(ASN)采购接收入库-补充
A) Via ROI Create a ASN [ship,ship] for a quantity =3 on STANDARD PURCHASE ORDER Create via R ...