linux c 中的守护线程
1.守护线程的概要
linux中的后台服务进程,必须要独立于控制终端并且周期性地执行某种任务或等待处理某些发生的事件
守护进程的特点
- Linux后台服务进程
- 独立于控制终端
- 不受用户登陆和注销的影响
- 一般 以用以d结尾的名字
守护进程的创建流程:
第一步: fork子进程,父进程退出(父进程不能创建守护进程)
第二步: 子进程调用 setsid 函数创建新会话
第三步:重设文件掩码 umask
- 进程会继承父进程的掩码
- 增加子进程程序操作的灵活性
第四步:关闭文件描述符
- 守护进程不受控制终端的影响所以可以关闭,以释放资源
第五步:执行核心任务
2.守护线程的案例实现
实现一个守护进程,每隔2S钟获取一次系统时间,并将这个时间写入磁盘文件。
// myDaemon.c
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>
#include<fcntl.h>
#include<sys/types.h>
#include<signal.h>
#include<sys/wait.h>
#include <sys/time.h>
#include <sys/stat.h>
#include<time.h>
void sighandler(int signo)
{
//int fd= open("time.log", O_RDWR|O_CREAT|O_APPEND, 0777);
int fd= open("time.log", O_RDWR|O_CREAT|O_APPEND, 0777);
if(fd<0)
{
perror("open error");
return;
}
time_t systime;
time(&systime);
//将时间转化为字符串
//char *ctime(const time_t *timep);
char *str=ctime(&systime);
write(fd,str,strlen(str));
//关闭资源
close(fd);
return;
}
int main(int argc,char * argv[])
{
pid_t pid=fork();
//1.创建子进程,父进程退出
if(pid<0||pid>0)
{
exit(0);
}
//第2步:子进程调用setsid函数创建新会话
setsid();
//第4步:重设文件掩码
umask(0000);// mode & ~umask
//Deamon 守护进程与终端无关,不需要 以下资源
close(STDIN_FILENO);
close(STDOUT_FILENO);
close(STDERR_FILENO);
//编写一个守护进程,每隔2S钟获取一次系统时间,并将这个时间写入磁盘文件。
//int setitimer(int which, const struct itimerval *restrict new_value,struct itimerval *restrict old_value);
struct itimerval itv;
itv.it_interval.tv_sec=2; //间隔两秒
itv.it_interval.tv_usec=0;
itv.it_value.tv_sec=3; //
itv.it_value.tv_usec=0;
setitimer(ITIMER_REAL,&itv,NULL);
//捕获信号
struct sigaction act;
act.sa_handler=sighandler;
sigemptyset(&act.sa_mask);
act.sa_flags=0;
//int sigaction(int signum, const struct sigaction *restrict act,struct sigaction *restrict oldact);
sigaction(SIGALRM,&act,NULL);
while(1) //这一步是防止子线程退出
{
sleep(1);//使用sleep 函数减少计算机资源损耗
}
return 0;
}
源文件
mydeamon.c
编译文件
make myDaemon
执行生成的可执行文件
./myDaemon
3.观察效果图
tail -f time.log
4.收尾工作
ps -aux 查找该进程
kill -9 3845 杀死该进程