zoukankan      html  css  js  c++  java
  • UNIX环境高级编程(13-守护进程)

    主要特点

    • 一般在系统启动时装入,仅在系统关闭时终止。
    • 大多数守护进程以超级用户特权运行。
    • 所有的守护进程都没有控制终端,其终端名设置为问号。
      • 内核守护进程以无控制终端方式启动。
      • 用户层守护进程可以通过调用setsid实现。
    • 用户层守护进程的父进程是init进程。

    消息输出

    前面提到,守护进程是没有控制终端的,显然无法将自己的消息输出到标准输出或标准错误上。而且系统中运行着许多守护进程,因此需要一个集中的守护进程记录设施,即syslog

    如上图所示,主要有3中产生日志消息的方式:

    1. 内核例程调用log函数
    2. 大多数用户进程调用syslog函数
    3. 将日志消息发送到UDP的514端口

    而syslogd守护进程接收这些日志消息,在其启动前会读取配置文件(/etc/syslog.conf),以决定各类消息的处理方式。

    #include <syslog.h>
    void openlog(const char *ident, int option, int facility);
    void syslog(int priority, const char *format, ...);
    void closelog(void);
    // Returns: previous log priority mask value
    int setlogmask(int maskpri);
    

    注:在没有调用openlog的情况下,先调用了syslog,会自动调用openlog

    ident参数指向的字符串会被加到日志消息中去,因此一般指定为程序名称。

    option参数指定各种选项的位屏蔽,选项见图13.3。

    facility参数可选值见图13.4。

    priority参数包含facility和level(图13.5)的组合,如果参数中没有指定facility,则会使用openlog中指定的facility,如果没有调用openlog,那么会使用默认值LOG_USER

    编程规则

    可以按照如下步骤编写一个守护进程。

    1. 调用umask函数将文件模式创建屏蔽字设置为指定值(通常为0)。守护进程可能需要创建一些文件,如果使用继承的屏蔽字,可能文件的权限会不符合预期。
    2. 调用fork后,使父进程exit。这样可以保证子进程不是进程组的组长进程。
    3. 调用setsid创建新会话。这可以保证当前进程没有控制终端,且成为新会话的首进程和新进程组的组长进程。
    4. 将当前工作目录改为根目录或某个指定位置。
    5. 关闭不再需要的文件描述符。可以使用getrlimit函数获取最高文件描述符值,并关闭直到该值的所有描述符。
    6. 某些守护进程将文件描述符0、1和2指向/dev/null,这样任何需要输入输出的库例程都不会产生影响。

    单实例守护进程

    某些守护进程在同一时刻只能运行一个实例程序,这时候可以使用文件和记录锁(下文简称文件锁,详见14章)来实现这个功能。

    守护进程只要创建一个固定名字的文件(一般在/var/run目录中),并在该文件整体上加一把写锁,那么此后其他的守护进程如果想要给该文件加锁就会失败,也就不应该继续运行。在守护进程终止时,锁会被自动删除,简化了复原过程。

  • 相关阅读:
    大型门户网站架构设计的可伸缩性
    服务器性能的瓶颈分析
    boost中bind、thread、io_services测试
    C++ 宏定义中字符串连接操作
    完成端口与高性能服务器程序开发
    异步IO、APC、IO完成端口、线程池与高性能服务器
    在模板类中使用字符串作为无类型模板参数
    VS2010 设置全局Include Directories与Library Directories
    Yii的Model ( 模型)创建及使用
    mvc中循环遍历分配的代码
  • 原文地址:https://www.cnblogs.com/maxiaowei0216/p/14250313.html
Copyright © 2011-2022 走看看