守護進程(setsid、getpgrp、setpgid、getpgid)以及系統日志(openlog、syslog、closelog)


守護進程:精靈進程

守護進程(Daemon)是運行在后台的一種特殊進程。它獨立於控制終端並且周期性地執行某種任務或等待處理某些發生的事件。

特點:

1.脫離控制終端

2.會話的leader

3.進程組的leader

=============================

系統日志:

[root]# cd /var/log/    系統日志

主日志文件:messages

syslogd服務----權限分離:每個用戶將要提交的日志提交給syslogd服務,syslogd將日志寫入系統日志

#include <syslog.h>
/********************************
 * 功能:   為進程與syslogd服務建立連接
 * 參數:   ident:給出的字段,
            option:特殊要求LOG_PID.....
            facility:消息來源:LOG_DAEMON.....
 ********************************/
void openlog(const char *ident, int option, int facility);

/********************************
 * 功能:   提交內容
 * 參數:   priority:級別:LOG_INFO.....
            format:提交的內容(變參)
 ********************************/
void syslog(int priority, const char *format, ...);

/********************************
 * 功能:   斷開進程與syslogd服務的連接
 *******************************/
void closelog(void);

=============================

[root]# ps axj  查看父子進程
tty:?脫離控制終端
SID PID PGID 相同
PPID:1

=============================

setsid:

#include <unistd.h>
/************************
 *功能:創建一個新的對話並設置進程組ID:如果當前調用它的進程不是進程組leader的情況下
 *返回值:成功返回進程ID,失敗返回-1並設置errno
 * *********************/
pid_t setsid(void);

=============================

getpgrp:

/***********************
 *功能:獲取進程組ID
 *返回值:成功返回進程組ID,失敗返回-1並設置errno
 * *********************/
int getpgrp(void);

=============================

/*****************************
 * 功能:設置進程組ID
 * 參數:pid進程ID
 *       pgid進程組ID
 ****************************/
int setpgid(pid_t pid, pid_t pgid);

/**************************
 * 功能:獲取進程GID
 * 參數:進程ID
 * ***********************/
pid_t getpgid(pid_t pid);

=============================

eg:

/***********************
 *功能:創建守護進程
 *      添加系統日志
 * ********************/
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <syslog.h>
#include <errno.h>

//守護進程創建后不斷向FNAME中寫入數字
#define  FNAME "/tmp/out"

static int daemonize(void )
{
    pid_t pid ;
    int fd ;
    int i ;
    //1.創建進程
    pid = fork();
    if(pid < 0)
        return -1;
    //2.子進程
    if(pid == 0)
    {
        //脫離控制終端 讀寫形式打開一個設備
        fd = open("/dev/null",O_RDWR);
        if(fd < 0)
            return -1 ;
        //重定向:將fd重定向到0 ,1 ,2
        dup2(fd , 0 );
        dup2(fd , 1 );
        dup2(fd , 2 );
        if(fd > 2)
            close(fd);

        //守護進程產生
        setsid();
        //當前的工作路徑為根目錄,如果是掛載的文件卸載可能回busy
        chdir("/");
        //在程序中不會產生文件的情況下
        umask(0);
        return 0 ;
    }
    else//2.父進程
        exit(0);
}

int main()
{
    FILE *fp ;
    int i ;
    //0.建立系統日志
    openlog("mydeamon",LOG_PID,LOG_DAEMON);

    //1.創建守護進程
    if(daemonize())
    {
        syslog(LOG_ERR ,"deamonize() failed !");
        exit(1);
    }
    else
    {
        syslog(LOG_INFO,"deamonize() success !");
    }
    //===========守護進程工作==============
    //2.以寫的方式打開文件
    fp = fopen(FNAME , "w");
    if(fp == NULL)
    {
        syslog(LOG_ERR,"fopen()%s",strerror(errno));
        exit(1);
    }
    syslog(LOG_INFO ,"%s was opened",FNAME);
    //3.不斷寫入i的值eg:1 2 3 4 ......
    for(i = 0 ;; i++)
    {
        fprintf(fp,"%d\n",i);
        //文件全緩沖模式,要加刷新
        syslog(LOG_DEBUG , "%d is printed ",i);
        fflush(fp);
        sleep(1);
    }
  //執行不到 fclose(fp); closelog(); exit(
0); }

[root]# ./demon

[root]# ps axj 查看deamon進程狀態

[root]# tail -f /tmp/out 動態查看文件內數值的變化

[root]# kill pid號   殺死進程

[root]# tail /var/log/messages 查看系統日志

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM