守护进程的介绍与使用

1.进程查看命令ps
(1)ps -ajx:偏向显示各种有关的ID
(2)ps -aux:偏向显示进程的各种占用资源

2.向进程发送信号命令kill
(1)kill -信号编号 进程ID,向一个进程发送一个信号
(2)kill -9 xxx,向xxx这个进程发生9号信号,也就是结束这个进程

3.何为守护进程
(1)daemon
(2)长期运行(一般是开机运行直到关机)
(3)与控制台脱离(关闭终端不会结束该进程,这个问题还在与会话)
(4)服务器(server)服务器就是一个一直在运行的程序,可以提供我们某种服务(譬如nfs给我们提供nfs服务通信方式),当我们需要需要这种服务时可以调用服务程序(和服务器程序通信得到服务程序帮助)来进程这种服务操作,服务程序一般都实现为守护进程。

4.常见的守护进程
(1)syslogd:系统日志守护进程,提供syslogd功能
(2)cron:实现操作系统的时间管理,linux中实现定时执行程序的功能要用到cron。

5.编写简单的守护进程
(1)任何一个进程都可以将自己实现成一个守护进程
(2)create_daemon函数要素实现以下六点就可以将一个进程变为守护进程
(2.1)子进程等待父进程退出
(2.2)子进程调用setsid创建新的会话期,脱离控制台
(2.3)调用chdir将当前工作目录设为/
(2.4)umask设置为0以取消任何文件权限屏蔽
(2.5)关闭所有文件描述符
(2.6)将0、1、2定位到/dev/null

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

//函数的作用就是把调用该函数的进程变为守护进程
void creat_daemon()
{
        pid_t pid = 0;
        pid = fork();
        if(pid < 0)
        {
                perror("fork");
        }
        //父进程
        else if(pid > 0)
        {
                exit(0);
                exit(-1);
        }
        //子进程
        //pid_t setsid(void);
        pid = setsid(); //将当前进程设置为新的会话期,目的就是让当前进程脱离控制台
        if(pid < 0)
        {
                perror("setsid");
                exit(-1);
        }
        //将当前目录设置为根目录
        //int chdir(const char *path);
        chdir("/");
        //umask设置为0确保将来进程有最大的文件操作权限
        //mode_t umask(mode_t mask);
        umask(0);
        //关闭所有文件描述符
        //先获取当前系统中所允许打开的最大文件描述符数目
        //long sysconf(int name);
        int cnt = sysconf(_SC_OPEN_MAX);
        for(int i;i<cnt;i++)
        {
                close(i);
		}
        //打开0、1、2文件描述符定位到/dev/null(垃圾堆目录)
        open("/dev/null",O_RDWR);
        open("/dev/null",O_RDWR);
        open("/dev/null",O_RDWR);

}

int main(void)
{
        creat_daemon();

        while(1)
        {
                printf("I am running\n");
                sleep(1);
        }

        return 0;
}

6.使用syslogd来记录调试信息
(1)openlog、syslog、closelog

void openlog(const char *ident, int option, int facility);
void syslog(int priority, const char *format, ...);
void closelog(void);

(2)各种参数
(3)编程实战:一般log信息都在操作系统的、var/log/message这个目录中存在,在ubuntu中在/var/log/syslog文件中

#include <stdio.h>
#include <syslog.h>
#include <sys/types.h>
#include <unistd.h>

int main(void)
{
        printf("my pid = %d\n",getpid());

        //void openlog(const char *ident, int option, int facility);
        openlog("a.out",LOG_PID|LOG_CONS,LOG_USER);
        //void syslog(int priority, const char *format, ...);
        syslog(LOG_INFO,"this is my log info");
        syslog(LOG_INFO,"this is another log info");
        //void closelog(void);
        closelog();

}

7.syslog工作原理
(1)操作系统有一个守护进程syslogd(开机运行,关机结束),这个守护进程syslogd负责进行日志文件的写入和维护。
(2)syslogd是独立于我们任何一个程序而运行的。我们当前进程和syslogd进程本来是没有任何关系的,但是当前可以调用openlog可以打开一条和syslogd相连接的通道,然后通过syslog向syslogd发消息,然后由syslogd来将其写入到日志文件系统中。
(3)syslogd其实就是一个日志文件系统的服务器进程,提供日志服务,任何需要写日志的进程都可以通过/openlog/syslog/closelog这三个函数利用syslogd提供的日志服务。

8.让程序不能被多次运行
(1)因为守护进程是长时间运行而不退出,因此./a.out执行一次就有一个守护进程,执行多次就有多个进程。
(2)这样并不是我们希望的,我们守护进程一般都是服务器,多次运行可能造成错误。
(3)因此我们希望程序有一个单例运行的功能,如果这个程序之前有这个程序的进程在运行则本次运行直接退出(提示程序已经在运行)
(4)实现方法:用一个文件的存在与否来做标志,当我们启动这个进程时,如果这个标志文件存在则表明进程已经在运行,反之亦然。当程序结束时去删除这个标志文件,这个标志文件要古怪一些,确保不会和电脑中已存在的文件重复。

#include <fcntl.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>

#define FILE "./aston_test_single"


void delete_file(void)
{
        remove(FILE);
        printf("删除成功\n");
}

int main()
{
        //程序执行之初判断文件是否处在
        int fd = -1;
        fd = open(FILE,O_RDWR|O_TRUNC|O_CREAT|O_EXCL,0664);
        if(fd < 0)
        {
                if(errno == EEXIST)
                {
                        printf("进程已存在请不要重复执行\n");
                        return -1;
                }
        }

        atexit(delete_file);    //注册进程清理函数
        for(int i=0;i<10;i++)
        {
                printf("I am running...%d\n",i);
                sleep(1);
        }

        return 0;
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值