守护进程实例


Linux守护进程:

守护进程是运行在后台的一种特殊进程,它无需用户输入就能够运行,经常是提供某种服务。Linux的大多数服务器就是用守护进程实现的。

守护进程的步骤

1 首先执行fork后,让父进程退出。

2 在子进程中调用setsid,取消进程与任何控制终端的关联。

3 让根目录成为子进程的当前工作目录。 chdir('/')

4 设置进程的umask = 0(设置权限)。

5 关闭子进程继承的任何不必要的文件描述符。


1 一个daemon实例:让后台运行的daemon程序向屏幕打印信息

一旦系统调用setsid,它就不再有控制终端,所以也就无处发送正常情况下应该发往stdout或者stderr的输出。

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <syslog.h>
#include<signal.h>
#include <fcntl.h>
#include<errno.h>
//让后台运行的daemon程序向屏幕打印信息
//创建一个守护进程
//一个信号捕捉函数
//一个回调函数listenfifo (读管道)

void setdaemon()
{
	int pid = fork();
		if(pid == -1)
		{
			printf("create fork error\n");
		}
		if(pid == 0)
		{
			printf("child begin\n");
			setsid();
			chdir("/");
			umask(0);
			//close(STDIN_FILENO);
			//close(STDOUT_FILENO);
			//close(STDERR_FILENO);
		}
		if(pid > 0)
		{
			exit(0);
		}
}

void catch_signal1(int sign)
{
	switch(sign)
	{
		case SIGINT:
			listenfifo();
			break;
	}
}
//创建一个读管道
void listenfifo()
{
	int len = 0;
	char buf[1024];
	memset(buf,0,sizeof(buf));
	int fd = open("/home/zxy/6/fifo1",O_RDONLY);
	if(fd == -1)
	{
		printf("open fifo1 error\n");
	}
	len = read(fd,buf,sizeof(buf));
	if(len > 0)
	{
		if(buf[strlen(buf) - 1] == '\n')
		{
			buf[strlen(buf) - 1] = 0;
		}
		close(STDOUT_FILENO);
		open(buf,O_WRONLY);
	}
	close(fd);

}
int signal1(int signo,void(*func)(int))
{
	struct sigaction act,oact;
	act.sa_handler = func;
	sigemptyset(&act.sa_mask);
	act.sa_flags = 0;
	return sigaction(signo,&act,&oact);
}

int main(void)
{
	setdaemon();
	signal1(SIGINT,catch_signal1);
	while(1)
	{
		printf("hello world\n");
		sleep(1);
	}
	return EXIT_SUCCESS;
}

还有一个守护进程是后台服务程序,所以只需一个进程即可,但此时可以创建多个相同的守护进程,没有意义,所以解决此办法是使用shell脚本进行编程。

通过shell脚本编程实现只能建立一个守护进程,实现启动守护进程、结束守护进程。

#! /bin/sh            #解释器
WHOAMI=`whoami`
PID=`ps -u $WHOAMI | grep /daemon | awk '{print $1}'`
if(test "$1" = "" ) then
	echo "daemon [start] [stop] [version]"
	exit 0
fi 
if(test "$1" = "status" ) then
	if(test "$PID" = "") then
		echo "not run"
	else
		echo " run"
	fi
	exit 0
fi
if(test "$1" = "start") then
	if(test "$PID" = "") then
		./daemon
	fi 
	exit 0
fi
if(test "$1" = "version") then
	echo "version is 1.1.1"
	exit 0
fi
if(test "$1" = "stop") then
        if(test "$PID" = "") then
             kill $PID
fi
 echo "daemon [start] [stop] [version]"



2 使用fifo与守护进程通信,实例:

readfifo_daemon.c代码

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <syslog.h>
#include<signal.h>
#include <fcntl.h>
#include<errno.h>
//使用fifo与守护进程通信
//先是创建守护进程
//建立读管道
void setdeamon()
{
	int pid = fork();
		if(pid == -1)
		{
			printf("ct=reate fork errror\n");
		}
		if(pid == 0)
		{
			setsid();
			chdir("/");
			umask(0);
		}
		if(pid > 0)
		{
			exit(0);
		}
}
void readfifo()
{
	int len = 0;
	char buf[1024];
	memset(buf,0,sizeof(buf));
	int fd = open("/home/zxy/6/fifo1",O_RDONLY);//返回打开的文件描述符
	if(fd == -1)
	{
		printf("open fifo error %s\n",strerror(errno));
		return;
	}
	while((len = read(fd,buf,sizeof(buf))) > 0)
	{
		printf("%s\n",buf);
		memset(buf,0,sizeof(buf));
	}
	close(fd);
	return;
}
int main(void)
{
	setdeamon();
	readfifo();


	return EXIT_SUCCESS;
}

writefifo_daemon.c代码:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <syslog.h>
#include<signal.h>
#include <fcntl.h>
#include<errno.h>

//创建写管道
void writefifo()
{
	int len = 0;
	char buf[1024];
	memset(buf,0,sizeof(buf));
	int fd = open("/home/zxy/6/fifo1",O_WRONLY);
	if(fd == -1)
		{
			printf("open fifo error %s\n",strerror(errno));
			return ;
		}
	while(1)
	{
		scanf("%s",buf);
		write(fd,buf,sizeof(buf));
		memset(buf,0,sizeof(buf));
	}

	close(fd);
	return;
}

int main()
{
	 writefifo();
	return 0;
}





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值