Linux下守护进程编写及将守护进程添加至服务

目录

一、什么是守护进程

二、守护进程范例

1.初始化守护进行函数

2.使用守护进程模板

三、将守护进程放到服务中


一、什么是守护进程

守护进程是一个在后台运行并且不受任何终端控制的进程。Unix操作系统有很多典型的守护进程(其数目根据需要或20—50不等),它们在后台运行,执行不同的管理任务。

用户使守护进程独立于所有终端是因为,在守护进程从一个终端启动的情况下,这同一个终端可能被其他的用户使用。例如,用户从一个终端启动守护进程后退出,然后另外一个人也登录到这个终端。用户不希望后者在使用该终端的过程中,接收到守护进程的任何错误信息。同样,由终端键人的任何信号(例如中断信号)也不应该影响先前在该终端启动的任何守护进程的运行。虽然让服务器后台运行很容易(只要shell命令行以&结尾即可),但用户还应该做些工作,让程序本身能够自动进入后台,且不依赖于任何终端。

守护进程没有控制终端,因此当某些情况发生时,不管是一般的报告性信息,还是需由管理员处理的紧急信息,都需要以某种方式输出。Syslog 函数就是输出这些信息的标准方法,它把信息发送给 syslogd 守护进程

二、守护进程范例

1.初始化守护进行函数

代码如下(示例):

#include <unistd.h>
#include <utmp.h>
#include <sys/msg.h>
#include <sys/un.h>
#include <sys/param.h>
#include <sys/stat.h>

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;
}

2.使用守护进程模板

代码如下(示例):

int main() 
{ 
	time_t now;
	char buf[128]= {0};
	init_daemon();
	int count = 100;
	
	FILE* fd = fopen("/var/daemon_test.log", "r+");
	while(count--) { 
		sleep(2);
		time(&now); 
		fprintf(fd, "SystemTime: \t%s\t\t\n",ctime(&now));
	} 
	
	fclose(fd);
    return 0;
}

此程序执行后悔自动变为后台程序,在后台进程中自动执行。


三、将守护进程放到服务中

创建AppName.service文件,内容如下,具体可搜索.service文件相关说明进行具体的编写

[Unit]
Description=ePass3000GM-daemon for manager ukey
After=syslog.target remote-fs.target nss-lookup.target

[Service]
Type=simple
ExecStart=/usr/sbin/secureid-daemon
ExecReload=/usr/sbin/secureid-daemon
EexcStop=killall secureid-daemon
RemainAfterExit=yes
Restart=no
 
[Install]
WantedBy=multi-user.target

将文件放入如下目录
/usr/lib/systemd/system/secureid-daemon.service

启动服务命令如下:

systemctl enable secureid-daemon.service
systemctl start secureid-daemon.service

这样程序便可开机自动启动,设置可以通过disable和stop命令进制开机自启和停止服务操作。

四、将守护进程放到服务中进程被杀死后自动重启

方法同三类似放入服务中,配置如下

[Unit]
Description=ePass3000GM-daemon for manager ukey
After=syslog.target remote-fs.target nss-lookup.target
StartLimitIntervalSec=0

[Service]
Type=simple
Restart=always
RestartSec=1
User=root
ExecStart=/usr/bin/secureid-daemon
#ExecReload=/usr/sbin/secureid-daemon
#EexcStop=killall secureid-daemon
#RemainAfterExit=yes

[Install]
WantedBy=multi-user.target

注意:此方法不能使用类似初始化守护进程,这个进程杀死后会自动重启,如果使用守护进行就会导致一直重启以为会一直检测主进程被杀死。其他方法同三类似可以实现服务方式启动程序。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
编写一个Linux守护进程,你可以按照以下步骤进行: 1. 创建一个新的进程,使用fork()函数。 2. 在子进程中,使用setsid()函数创建一个新的会话,并将子进程设置为会话的首进程。 3. 关闭父进程,使用exit()函数。 4. 在子进程中,更改工作目录到根目录,可以使用chdir("/")函数。 5. 设置文件权限掩码为0,这样可以避免继承父进程的文件权限,使用umask(0)函数。 6. 关闭标准输入、标准输出和标准错误输出,可以使用close()函数或dup2()函数。 7. 打开日志文件,并将标准输出和标准错误输出重定向到日志文件。 8. 进入守护进程的主循环,在循环中执行相应的任务。 下面是一个简单的示例代码: ```c #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> int main() { // 创建一个新的进程 pid_t pid = fork(); // 子进程 if (pid == 0) { // 创建一个新的会话并设置子进程为会话首进程 setsid(); // 关闭父进程 exit(0); } // 更改工作目录到根目录 chdir("/"); // 设置文件权限掩码为0 umask(0); // 关闭标准输入、标准输出和标准错误输出 close(STDIN_FILENO); close(STDOUT_FILENO); close(STDERR_FILENO); // 打开日志文件并重定向标准输出和标准错误输出 int log_fd = open("/var/log/mydaemon.log", O_RDWR | O_CREAT, 0644); dup2(log_fd, STDOUT_FILENO); dup2(log_fd, STDERR_FILENO); // 守护进程的主循环 while (1) { // 执行任务 // ... } return 0; } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值