守护进程
来源:互联网 发布:淘宝商城女装 编辑:程序博客网 时间:2024/05/01 08:51
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
/* Daemonize myself.
守护进程,也就是通常说的Daemon进程,
是Linux中的后台服务进程。
它是一个生存期较长的进程,
通常独立于控制终端并且周期性地执行
某种任务或等待处理某些发生的事件。
守护进程常常在系统引导装入时启动,
在系统关闭时终止。Linux系统有很多守护进程,
大多数服务都是通过守护进程实现的,同时,
守护进程还能完成许多系统任务,例如,
作业规划进程crond、打印进程lqd等
(这里的结尾字母d就是Daemon的意思)。 */
void sigterm_handler(int arg)
{
_running=0;
}
int
daemon (int nochdir, int noclose)
{
pid_t pid;
pid = fork ();
/* In case of fork is error. */
if (pid < 0)
{
perror ("fork");
return -1;
}
/* In case of this is parent process. */
if (pid != 0) //先让父进程退出
exit (0);
// 会话周期:会话期是一个或多个进程组的集合。通常,
//一个会话开始于用户登录,终止于用户退出,在此期间该用户运行的所有进程都属于这个会话期。
//setsid函数用于创建一个新的会话,并担任该会话组的组长
/* Become session leader and get pid. */
pid = setsid();
if (pid < -1)
{
perror ("setsid");
return -1;
}
/* Change directory to root. 使用fork创建的子进程继承了父进程的当前工作目录,要改变*/
if (! nochdir)
chdir ("/");
/* File descriptor close. */
if (! noclose)
{
int fd;
fd = open ("/dev/null", O_RDWR, 0);
if (fd != -1)
{
// 如果想让某个进程不因为用户或终端或其他地变化而受到影响,
//那么就必须把这个进程变成一个守护进程。守护进程是脱离控制终端,
//在Linux中父进程先于子进程退出会造成子进程成为孤儿进程,而每当系统发现一个孤儿进程时,
//就会自动由1号进程(init)收养它,这样,原先的子进程就会变成init进程的子进程。
// setsid函数用于创建一个新的会话,
//并担任该会话组的组长。调用setsid有下面的3个作用:
//让进程摆脱原会话的控制 让进程摆脱原进程组的控制
//让进程摆脱原控制终端的控制
//那么,在创建守护进程时为什么要调用setsid函数呢?
//由于创建守护进程的第一步调用了fork函数来创建子进程,
//再将父进程退出。由于在调用了fork函数时,子进程全盘拷贝了父进程的会话期
//、进程组、控制终端等,虽然父进程退出了,但会话期、进程组、
//控制终端等并没有改变,因此,这还不是真正意义上的独立开来,
//而setsid函数能够使进程完全独立出来,从而摆脱其他进程的控制。
dup2 (fd, STDIN_FILENO);
dup2 (fd, STDOUT_FILENO);
dup2 (fd, STDERR_FILENO);
if (fd > 2)
close (fd);
}
}
文件权限掩码是指屏蔽掉文件权限中的对应位。比如,有个文件权限掩码是050,它就屏蔽了文件组拥有者的可读与可执行权限。
//由于使用fork函数新建的子进程继承了父进程的文件权限掩码,
//这就给该子进程使用文件带来了诸多的麻烦。因此,
//把文件权限掩码设置为0,可以大大增强该守护进程的灵活性。
//设置文件权限掩码的函数是umask。在这里,通常的使用方法为umask(0)。
//当用户需要外部停止守护进程运行时,
//往往会使用 kill命令停止该守护进程。所以,
//守护进程中需要 编码来实现kill发出的signal信号处理,
//达到进程的正常退出。
signal(SIGTERM, sigterm_handler);
umask (0027);
关闭文件描述符
同文件权限码一样,用fork函数新建的子进程会从父进程那里继承一些已经打开了的文件。
//这些被打开的文件可能永远不会被守护进程读写,
//但它们一样消耗系统资源,而且可能导致所在的文件系统无法卸下。
for(int i=0;i<MAXFILE;i++)
close(i);
while(_running)
{
if((fd=open("/tmp/dameon.log",O_CREAT|O_WRONLY|O_APPEND,0600))<0)
{
perror("open");
exit(1);
}
}
return 0;
}
int main(void)
{
daemon(0,0);
sleep(1000);
return 0;
}
- 守护进程守护自身
- 守护线程、守护进程
- 守护进程
- 守护进程
- 守护进程
- 守护进程
- 进程守护
- 守护进程
- 守护进程
- 守护进程
- 守护进程
- 守护进程
- 守护进程
- 守护进程
- 守护进程
- 守护进程
- 守护进程
- 守护进程
- 在WCF中用TcpTrace工具查看发送和接收的SOAP消息
- 标签页及分页技术的实现
- A Interesting Interview(有趣的面试)
- svn server配置 authz 多工程的访问权限设置
- 解决Quartus II 11.0 build Error :Current license file dose not support the EP2C8Q208C8 device .
- 守护进程
- shell : start x11vnc
- EFM32片内外设--USB MSD host framework
- C++中Explicit关键字的理解
- Maven和Tycho
- linux c 单例执行程序
- 正则表达式学习(九)子表达的使用
- ios 下拉刷新
- HDOJ 1536 SG函数的基本应用