zoukankan      html  css  js  c++  java
  • Linux 守护进程一

    守护进程是一个后台进程,它无需用户输入就能运行,经常是提供某种服务。
    LInux作为服务器,主要的进程也都是为系统或用户提供后台服务功能。
    常见的守护进程有Web服务器、邮件服务器以及数据库服务器等等。
    守护进程不能够控制终端,所以任何输入或者输出都需要做特殊处理。
    守护进程程序的名字默认规则需要以d字母结尾
    守护进程看上去似乎很神秘,但如果牢记几条规则而且知道几个关键函数,工作就很简单了。
    首先执行fork后让父进程退出。
    和多数程序一样,一个守护进程是从shell脚本或者命令行启动的。
    但守护进程和应用程序不一样,因为他们不是交互式的,他们在后台因而没有控制终端。
    父进程在fork子进程退出后就消除了控制终端。
    守护进程既不需要从标准输入设备读信息,也不需要从标准输出设备输出信息。
    下一步是在子进程中调用setsid,取消进程和任何控制终端的关联。
    下一步是让根目录成为子进程的当前工作目录。
    因为任何进程如果他的当前目录是在一个被安装的文件系统上,那么就会妨碍这个文件系统被卸载。
    接下来设置进程的umask为0。
    为了避免守护进程集成的umask收到创建文件和目录操作的干扰,这一步是必要的。
    如果一个进程集成了父进程的umask 055,它屏蔽掉了group和other的读和执行权。如果守护进程接着创建了一个文件,那么对group和other用户操作这个文件会带来麻烦。
    守护进程调用umask 0避免了这种情况,当创建文件的时候给予守护进程更大的灵活性。
    最后关闭子进程继承的任何不必要的文件描述符。
    对于子进程来说,没有理由保持从父进程继承的被打开的文件描述符
    具体关闭哪些取决于具体的守护进程需要和要求,很难精确的说明规则。
    创建守护进程步骤总结
    --父进程中执行fork后,执行exit退出。
    --在子进程中调用setsid。
    --让根目录"/"成为子进程的工作目录。
    --把子进程的umask变为0(子进程会继承父进程的umask,所以如果在父进程中设置了umask,子进程可以不必设置)。
    --关闭任何不需要的文件描述符。
    setsid函数
    pid_t setsid(void)
    setsid函数创建一个新会话和一个新进程组,然后守护进程成为新会话的会话领导,以及新进程组的进程组领导。
    setsid调用还保证新会话没有控制终端。
    如果调用进程已经是一个进程组的领导进程,setsid调用失败。
    setsid调用成功返回新会话ID,失败返回-1,并设置errno。
    setsid调用只能够调用一次。
    setsid函数实现了与控制台脱离关系,控制台关闭将不会影响守护进程。
    chdir函数
    int chdir(const char *pathname)
    chdir函数根据参数pathname设置当前工作。
    chdir调用成功返回0,失败返回-1,并设置errno。
    强调:当前工作目录是指在哪个目录下执行该程序的那个目录,并不一定是该程序文件所在的目录。
    umask函数
    mode_t umask(mode_t mask);
    umask调用把守护进程的umask设置为0,这样取消了来自父进程的umask,
    它们能够潜在的干扰创建文件和目录(umask函数一般是来设置文件权限的,不设置umask,有可能创建的文件其他用户无法操作)
    syslog系统日志
    一旦系统调用setsid,他就不再有控制终端。
    可以通过syslog提供服务,记录守护进程的各种输出信息。
    openlog函数打开系统日志,syslog写入日志,closelog关闭系统日志。
    void open(const char *ident,int option,int facility);
    void syslog(int priority,const char *format);
    void closelog(void);
    openlog函数发起到系统日志服务器的连接,参数ident是要向没个消息加入的字符串,典型的情况是要设置成程序的名称
    参数option是下面一个或多个值
    LOG_CONS    如果系统日志服务器不能用,写入控制台
    LOG_NDELAY    立刻打开链接,正常情况下,直到发送第一条信息才打开连接
    LOG_PERROR    打开输出到stderr
    LOG_PID            每条信息中包含进程PID
    
    参数facitity指定程序发送消息的类型
    LOG_AUTHPRIV    安全授权消息
    LOG_CRON    时钟守护进程:cron和at
    LOG_DAEMON    其他系统守护进程
    LOG_KERN    内核消息
    LOG_LPR        打印机子系统
    LOG_MAIL    邮件子系统
    LOG_USER    默认
    
    参数priority指定消息的重要性
    LOG_EMERG    系统不能使用
    LOG_ALERT    立即采取措施
    LOG_CRIT    紧急事件
    LOG_ERR        出错条件
    LOG_WARNING    警告条件
    LOG_NOTICE    正常但重大事件
    LOG_INFO    信息消息
    LOG_DEBUG    调试信息
    
    syslog代码例子:
    syslog("LOG_INFO","my daemin is ok");
    严格的说,openlog和closelog是可选的,因为函数syslog在首次使用的时候自动打开日志文件。
    Linux系统上日志文件通常是/var/log/messages。
    和一个守护进程通信,你需要向它发送信号,让它以某种方式响应。
    例如:强行要求一个守护进程重新读取它的配置文件,或者改变守护进程的行为,或者指示守护进程结束运行。
    通过shell脚本结束守护进程,shell脚本写完后需要修改脚本属主可执行权限
    shell脚本解释
    #!/bin/sh 用这个命令来执行脚本文件。 WHOAMI=`whoami` 定义一个变量WHOAMI(变量名一般大写);`whoami`双反单引号表示在命令行执行whoami命令, 并且将结果保存在变量WHOAMI中 PID=`ps -u $WHOAMI | grep tecd | awk '{print $1}'` 执行命令,并且将命令结果作为变量PID的值, ps -u $WHOAMI 获取当前用户的进程列表 grep tecd 在列表中查找tecd这个字符串,并返回带有这个字符串的记录列表 awk 获取一条信息的某部分 print $1 获取这条信息的第一列数据,$2获取这条信息的第二列数据 if( test "$PID" != "") then kill -s 2 $PID fi

    启动守护进程shell脚本

    #!/bin/sh
    
    WHOAMI=`whoami`
    
    PID=`ps -u $WHOAMI | grep tecd | awk '{print $1}'`
    
    if(test "$PID" = "") then
        ./tecd
    fi

    关闭守护进程shell脚本

    #!/bin/sh   
    
    WHOAMI=`whoami`        
    
    PID=`ps -u $WHOAMI | grep tecd | awk '{print $1}'`
    
    if( test "$PID" != "") then
        kill -s 2 $PID
    fi
  • 相关阅读:
    9.Vue技术栈开发实战-使用Mock模拟Ajax请求
    8.Vue技术栈开发实战-Ajax请求实战
    7.Vue技术栈开发实战-状态管理Vuex进阶
    6.Vue技术栈开发实战-状态管理Vuex(二)
    5.Vue技术栈开发实战-状态管理Vuex(一)
    4.Vue技术栈开发实战-状态管理bus的使用
    3.Vue技术栈开发实战-路由进阶篇
    2.Vue技术栈开发实战-路由基础篇
    Vue技术栈开发实战_汇总贴
    1.Vue技术栈开发实战-使用vue-cli3创建项目
  • 原文地址:https://www.cnblogs.com/zhanggaofeng/p/5850091.html
Copyright © 2011-2022 走看看