提高网站建设管理水平,网络工程师考试时间,淘宝联盟推广网站建设,装企erp管理系统Q#xff1a;什么是守护进程
A#xff1a;Linux Daemon#xff08;守护进程#xff09;是运行在后台的一种特殊进程。它独立于控制终端并且周期性地执行 某种任务或等待处理某些发生的事件。它不需要用户输入就能运行而且提供某种服务#xff0c;不是对整个系统就是对某个…Q什么是守护进程
ALinux Daemon守护进程是运行在后台的一种特殊进程。它独立于控制终端并且周期性地执行 某种任务或等待处理某些发生的事件。它不需要用户输入就能运行而且提供某种服务不是对整个系统就是对某个用户程序提供服务。Linux系统的大多数服务器就是通过守护进程实现的。常见的 守护进程包括系统日志进程syslogd、 web服务器httpd、邮件服务器sendmail和数据库服务器 mysqld守护进程的名称通常以d结尾 守护进程的基本特点
生存周期长非必须一般操作系统启动的时候就启动关闭的时候关闭守护进程和终端无关联也就是他们没有控制终端所以当控制终端退出也不会导致守护进程退出守护进程是在后台运行不会占着终端终端可以执行其他命令一个守护进程的父进程是init进程因为它真正的父进程在fork出子进程后就先于子进程exit退出了所以它是一个由init继承的孤儿进程
linux操作系统本身是有很多的守护进程在默默执行维持着系统的日常活动。大概30-50个
输入“ps -elf”指令, 显示系统中所有进程的列表包括其他用户的进程(-ef, 并用长格式显示(-l) ps -aux 也可以显示这些进程只不过显示的内容不大一样比如-aux还会显示进程的状态CPU和内存显示情况 其中
ppid 0内核进程跟随系统启动而启动生命周期贯穿整个系统cmd列名带“ [ ] ”这种叫内核守护进程老祖init就是CMD列第一个也是系统守护进程它负责启动各运行层次特定的系统服务所以很多进程的PPID是init也负责收养孤儿进程cmd列中名字不带“ [ ] ”的这种叫普通守护进程用户集守护进程 守护进程和后台进程的区别
守护进程和终端不挂钩后台进程能往终端上输出东西(和终端挂钩)守护进程关闭终端时不受影响守护进程不会随着终端的退出而退出 Q如何启动后台进程 A: 可以选择在执行语句后加上“ ”空格加意思是后台运行 守护进程的开发方式
使用damon函数结合两个C库的时间函数来实现一个“每隔10秒向/home/orangepi/daemon.log写入当前时间”的守护进程
damon()函数
#include unistd.h
int daemon(int nochdir, int noclose);
nochdir为0时表示将当前目录更改至“/”noclose为0时表示将标准输入、标准输出、标准错误重定向至“/dev/null”返回值 成功则返回0失败返回-1
C库函数——asctime()
char *asctime(const struct tm *timeptr)
返回一个指向字符串的指针它代表了结构 struct timeptr 的日期和时间
C库函数——localtime()
struct tm *localtime(const time_t *timer)
使用 timer 的值来填充 tm 结构。 timer 的值被分解为 tm 结构并用本地时区表示 struct tm {int tm_sec; //秒范围从 0 到 59int tm_min; //分范围从 0 到 59int tm_hour; //小时范围从 0 到 23int tm_mday; //一月中的第几天范围从 1 到 31int tm_mon; //月份范围从 0 到 11int tm_year; //自 1900 起的年数int tm_wday; //一周中的第几天范围从 0 到 6int tm_yday; //一年中的第几天范围从 0 到 365int tm_isdst; //夏令时
}; time_daemon.c
#include unistd.h
#include signal.h
#include stdlib.h
#include string.h
#include fcntl.h
#include sys/stat.h
#include time.h
#include stdio.h
#include stdbool.hstatic bool flag true;void handler(int sig)
{printf(I got a signal %d\nIm quitting.\n, sig);flag false; //当检测到退出信号时将flag置为false使得main中的while退出循环
}int main()
{time_t t;int fd;//创建守护进程if(-1 daemon(0, 0)){printf(daemon error\n);exit(1);}//设置信号处理函数//由于守护进程的标准输入、标准输出、标准错误都被重定向到了“/dev/null”所以影响这个进程的方式只能是信号struct sigaction act; //这里选择使用sigaction函数定义sigaction结构体act.sa_handler handler; //但是却给sa_handler赋值而不是sa_sigaction所以还是相当于使用了signal函数sigemptyset(act.sa_mask); //将信号集清空act.sa_flags 0;if(sigaction(SIGQUIT, act, NULL)) //和上面所说一样由于没有定义sa_sigaction所以实现的效果就和signal函数一样即收到“SIGQUIT”信号的时候执行handler函数{printf(sigaction error.\n);exit(0);}//进程工作内容while(flag){fd open(/home/orangepi/daemon.log, O_WRONLY | O_CREAT | O_APPEND,0644); //只写打开O_WRONLY文件不存在就创建O_CREAT每次写都加到文件的尾端O_APPEND主用户可读可写6其他用户只能读4if(fd -1){printf(open error\n);}t time(0); //类似初始化char *buf asctime(localtime(t)); //localtime将t分解为tm结构asctime将tm结构解析成时间的字符串write(fd, buf, strlen(buf));close(fd);sleep(10); //每隔10S写入一次}return 0;
} 实现效果
编译并运行 此时看起来什么都没有发生但其实守护进程已经开始跑起来了可以使用“ps -ef|grep a.out” 指令来验证 可见8412就是这个守护进程的PID号8472是grep的可以无视
同时cd到根目录下并“ls” 出现了这个“daemon.log”的文件
然后此时调用SIGQUIT来结束这个守护进程并验证 成功退出最后打开daemon.log 可见时间信息确实不断的追加打印到了这个文件并且只要不调用SIGQUIT哪怕关掉终端也不会结束运行只有系统关闭才会关闭。
且守护进程一般是开机自启的实现这一点可以通过“sudo vi /etc/rc.local”然后添加守护进程的绝对路径来实现 注意这里的路径应该是可执行文件的绝对路径而不是C文件的绝对路径所以需要再次编译一下C文件起一个名字且如果想在这个文件下写多个路径直接分多行写就可以对于非守护进程如果也想写入文件进行开机自启可以选择在路径后加上“ ”空格加意思是后台运行 保存退出后执行“sudo reboot” 重新启动
重新启动后使用“ps -ef|grep time_daemon” 指令来查看是否开机自启 可见成功实现了开机自启此时同样输入“sudo kill -3 2331” 来关闭这个守护进程然后打开daemon.log 可见在之前的基础上又追加写入了很多次的时间信息