第一天内容
进程的基本概念
进程控制相关的系统调用
今天学的内容
创建守护进程
守护进程的概念
守护进程、控制终端、进程组、会话期
为什么要编写守护进程
如何编写守护进程
和昨天说的一样,这里只给出大概方向,如果同学们有兴趣还请自行爬文。
Linux中后台运行 ./filename &
创建守护进程
实现守护进程的步骤
让init进程成为新产生进程的父进程
调用setsid函数
更改当前工作目录
关闭文件描述符,并重定向标准输入、输出和错误输出
设置守护进程的文件权限创建掩码
让init进程成为新产生进程的父进程
调用setsid函数
更改当前工作目录
关闭文件描述符,并重定向标准输入、输出和错误输出
设置守护进程的文件权限创建掩码
让init进程成为新产生进程的父进程
pid = fork();
if (pid > 0) exit(0);
调用setsid函数
新创建的进程脱离控制终端
创建新的进程组
新创建的进程成为该进程组的首进程
#include<unistd.h>
pid_t setsid(void)
新创建的进程脱离控制终端
创建新的进程组
新创建的进程成为该进程组的首进程
#include<unistd.h>
pid_t setsid(void)
更改当前目录
使用fork函数产生的子进程将继承父进程的当前工作目录
当进程没有结束,其工作目录不能被卸载
守护进程一般将其工作目录更改到根目录下
#include<unistd.h>
int chdir(const char *path);
使用fork函数产生的子进程将继承父进程的当前工作目录
当进程没有结束,其工作目录不能被卸载
守护进程一般将其工作目录更改到根目录下
#include<unistd.h>
int chdir(const char *path);
关闭文件描述符,并重定向标准输入、输出和错误输出
可以使用dup2函数将标准输入/输出/错误输出重定向到/dev/null设备(空设备,向其写入数据没有任何输出。
#include<unistd.h>
int dup2(int oldfd,int newfd)
#include<unistd.h>
int dup2(int oldfd,int newfd)
设置守护进程的文件权限创建掩码
守护进程常要创建一些临时文件
这些文件不希望被别的用户查看
可以使用umask函数修改文件的权限,创建掩码的取值,以满足守护进程的要求
#include<sys/types.h>
#include<sys/stat.h>
mode_t umask(mode_t mask);
语法: umask [-s] [权限掩码]
权限掩码是由3个八进制的数字所组成,将现有的存取权限减掉掩码后,就是建立文件时预设的权限
文件初始权限 110 目录初始权限111 RWX
n
范例 实现一个守护进程的例子
int init_daemon(void)
{
int pid;
int i;
/*忽略终端I/O信号,STOP信号*/
signal(SIGTTOU,SIG_IGN);
signal(SIGTTIN,SIG_IGN);
signal(SIGTSTP,SIG_IGN);
signal(SIGHUP,SIG_IGN);
pid = fork();
if(pid > 0) { exit(0); /*结束父进程,使得子进程成为后台进程*/ }
else if(pid < 0) { return -1; }
/*建立一个新的进程组,在这个新的进程组中,子进程成为这个进程组的首进程,以使该进程脱离所有终端*/
setsid();
/*再次新建一个子进程,退出父进程,保证该进程不是进程组长,同时让该进程无法再打开一个新的终端*/
pid=fork();
if( pid > 0) { exit(0); }
else if( pid< 0) { return -1; }
/*关闭所有从父进程继承的不再需要的文件描述符*/
for(i=0;i< NOFILE;close(i++));
/*改变工作目录,使得进程不与任何文件系统联系*/
chdir("/");
/*将文件当时创建屏蔽字设置为0*/
umask(0);
/*忽略SIGCHLD信号*/
signal(SIGCHLD,SIG_IGN);
return 0;
}
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <signal.h>
#include <sys/param.h>
#include <sys/stat.h>
#include <time.h>
#include <syslog.h>
int main()
{
time_t now;
init_daemon();
syslog(LOG_USER|LOG_INFO,"测试守护进程! \n");
while(1) {
sleep(8);
time(&now);
syslog(LOG_USER|LOG_INFO,"系统时间: \t%s\t\t\n",ctime(&now));
}
}