3.linux的守护进程

17.08.25
运行环境:mac
参考学习这里: https://wenku.baidu.com/view/32cdfa48cc22bcd126ff0ceb.html
需要自己动手实现一个守护进程,当控制台窗口关闭时还可以在后台运行,每隔一秒钟向my.log文件中插入一条时间记录
守护进程(daemon)是一类在后台运行的特殊进程,用于执行特定的系统任务。很多守护进程在系统引导的时候启动,并且一直运行直到系统关闭。另一些只在需要的时候才启动,完成任务后就自动结束
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<signal.h>
#include<time.h>
void writelog(const char *log)
{
	time_t tDate;
	struct tm *eventTime;
	time(&tDate);//得到系统时间
	eventTime = localtime(&tDate);//将时间格式化为struct tm结构
	int iYear = eventTime-> tm_year + 1900;
	int iMon = eventTime->tm_mon + 1;
	int iDay = eventTime-> tm_mday;
        int iHour = eventTime->tm_hour;
	int iMin = eventTime-> tm_min;
        int iSec = eventTime->tm_sec;
	char sDate[16];
	sprintf(sDate,"%04d-%02d-%02d",iYear,iMon,iDay);
	char sTime[16];
	sprintf(sTime,"%02d:%02d:%02d",iHour,iMin,iSec");
	char s[1024];
	sprintf(s,"%s %s %s\n",sDate,sTime,log);//将s格式化为yyyy-mm-dd hh:mi:se log格式
	FILE *fd = fopen("my.log","a+");//以追加方式打开my.log文件
	fputs(s,fd);//向my.log文件写入一行记录
	fclose(fd);//关闭文件	
}
void setdaemon()
{
	pid_t pid,sid;
	pid = fork();
	if(pid < 0){
		printf("fork failed\n");
		exit(EXIT_FAILURE);
	}	
	if(pid > 0){
		exit(EXIT_SUCCESS);//在父进程中
	}
	if((sid = setsid()) < 0){ 	//子进程,如果setsid()调用成功,会返回新的会话的ID
		printf("setsid failed\n");
		exit(EXIT_FAILURE);
	}


}
int main(int arg,char *args[])
{
	setdaemon();//将进程设置为daemon状态
	char buf[100];	
	int i = 0;
	while(1){
		memset(buf,0,sizeof(buf));
		sprintf(buf,"log %d",i++);
		writelog(buf);//写入文件
		sleep(1);		
	}
}
慢慢解读这份源代码,首先 将进程设置为daemon状态
关于daemon状态, setsid函数可以参考博客: http://www.cnblogs.com/boodoog/p/6043083.html
引用一波:
使用setsid函数的目的:由于创建守护进程的第一步调用了fork函数来创建子进程再将父进程退出。由于在调用fork函数时,子进程拷贝了父进程的会话期、进程组、控制终端等,虽然父进程退出了,但会话期、进程组、控制终端等并没有改变,因此,这还不是真正意义上的独立开了。使用setsid函数后,能够使进程完全独立出来,从而摆脱其他进程的控制。
顺便普及一下这份源代码所用到的一些知识:
spintf:格式化字符串的c函数, https://baike.baidu.com/item/sprintf/9703430?fr=aladdin
fopen: a+代表追加方式, https://baike.baidu.com/item/fopen/10942321?fr=aladdin#1
这样的一个程序当我们编译并且运行后就会变成后台的守护进程,此时如果我们要结束这个守护进程,可以在mac下的活动监视器找到该进程直接杀死。
或者:使用命令行的方式:
1. killall 进程名称
2.参考: http://blog.csdn.net/zhshow/article/details/6042338,使用命令
  ps aux | grep 进程名字 
可以看到该进程对应的信息,比如说pid,再使用kill命令杀死进程:
kill pid
在活动监视器中就可以看到该进程被杀死了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值