-
守護進程daemon
Unix/Linux中的守護進程(Daemon)類似於Windows中的後臺服務進程,一直在後臺長時間運行的進程。它通常在系統啓動後就運行,沒有控制終端,也無法和前臺的用戶交互,在系統關閉時才結束。Daemon程序一般都作爲服務程序使用,等待客戶端程序與它通信。我們也把運行的Daemon程序稱作守護進程。比如的網絡服務程序,可以在完成創建套接口,綁定套接口,設置套接口爲監聽模式後,變成守護進程進入後臺執行而不佔用控制終端,這是網絡服務程序的常用模式。UNIX下的網絡服務程序,如WebServer(Nginx、Apache等),FTP(vsftp),SSH(openssh)等一般都是由守護進程(Daemon)來實現的。守護進程不佔用終端,在後臺運行。UNIX的守護進程一般都命名爲 *d 的形式,如httpd,vsftpd,sshd等。守護進程一旦脫離了終端,退出就成了問題,這時需要使用 ps 命令查出進程ID然後再使用kill命令停止。
Linux系統專門提供了一個用來創建daemon進程的庫函數,該函數的原型是
#include <unistd.h> //包含daemon頭文件
int daemon(int nochdir, int noclose);
-
參數
-
nochdir
指定是否要切換當前工作路徑到"/“根目錄,
2.noclose
指定是否要關閉標準輸入、標準輸出和標準出錯(即重定向到/dev/null)。
-
在創建守護進程的時候,往往需要將進程的工作目錄修改爲”/"根目錄,並將標準輸入、標準輸出和標準出錯關閉。所以這兩個參數我們一般都是傳0。
-
編程示例
#ifndef __DAEMON_H__
#define __DAEMON_H__
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <syslog.h>
#include <libgen.h>
#endif
int main (int argc, char *argv[])
{
char *progname = basename(argv[0]);
if ( daemon(1,1) < 0) //實行daemon
{
printf("Program daemon failure:%s\n", strerror(errno));
return -1;
}
openlog("daemon",LOG_CONS | LOG_PID,0);
syslog(LOG_NOTICE, "program '%s' start running\n",progname);
syslog(LOG_WARNING, "program '%s' running with a warnning message\n", progname);
syslog(LOG_EMERG, "program '%s' running with a emergency message\n",progname);
while (1)
{
//do something;
}
syslog(LOG_NOTICE, "program '%s' stop running\n", progname);
closelog();
return 0;
}
- 我們可以在使用以下命令來查看daemon程序的信息
ps -aux |grep daemon
- 如果想要kill daemon這個程序:
killall daemon
-
日誌系統syslog
syslog是一種工業標準的協議,可用來記錄設備的日誌。在UNIX系統,路由器、交換機等網絡設備中,系統日誌(System Log)記錄系統中任何時間發生的大小事件。管理者可以通過查看系統記錄,隨時掌握系統狀況。UNIX的系統日誌是通過syslogd這個進程記錄系統有關事件記錄,也可以記錄應用程序運作事件。通過適當的配置,我們還可以實現運行syslog協議的機器間通信,通過分析這些網絡行爲日誌,藉以追蹤掌握與設備和網絡有關的狀況。
-
函數原型:
#include <syslog.h> //需要包含頭文件
void openlog(const char *ident, int option, int facility); //打開系統日誌
void syslog(int priority, const char *format, ...); //寫入日誌系統
void closelog(void); //關閉日誌系統
-
openlog函數及其參數說明 (打開系統日誌)
-
參數說明:
1、ident:
是一個標記,ident 所表示的字符串將固定的加在每行日誌的前面一標識這個日誌,通常就寫成當前程序的名稱以作標記。
2、option:
指定openlog函數和接下來調用的syslog函數的控制標誌
option | 說明 |
LOG_CONS | 如果將信息發送給 syslogd 守護進程時發生錯誤,直接將相關信息輸出到終端 |
LOG_NDELAY | 立即打開與系統日誌的連接(通常情況下,只有在產生第一條日誌信息的情況下才會打開與日誌系統的連接) |
LOG_ODELAY | 類似於 LOG_NDELAY 參數,與系統日誌的連接只有在 syslog 函數調用時纔會創建 |
LOG_PERROR |
在將信息寫入日誌的同時,將信息發送到標準錯誤輸出 |
LOG_PID | 每條日誌信息中都包含進程號 |
3、facility:
指定記錄消息程序的類型,與 syslogd 守護進程的配置文件 syslog.conf 中的 facility 對應。
facility | 說明 |
---|---|
LOG_AUTH | 認證系統(login、su、getty等) |
LOG_AUTHPRIV | 同 LOG_AUTH 但只登陸到所選擇的單個用戶可讀的文件中。 |
LOG_CRON | cron 守護進程 |
LOG_DAEMON | 其他系統守護進程,如 routed |
LOG_FTP | 文件傳輸協議:ftpd、tftpd |
LOG_KERN | 內核產生的消息 |
LOG_LPR | 系統打印機緩衝池:lpr、lpd |
LOG_MAIL | 電子郵件系統 |
LOG_NEWS | 網絡新聞系統 |
LOG_SYSLOG | 由 syslogd(8)產生的內部消息 |
LOG_USER | 隨機用戶進程產生的消息 |
LOG_UUCP | UUCP子系統 |
LOG_LOCAL0~LOG_LOCAL7 | 本地使用保留 |
-
syslog函數及其參數說明 (寫入日誌,與文件系統調用 printf使用方法類似,但在前面指定日誌級別。)
-
參數說明
- priority:
表示消息的級別,與 syslogd 守護進程的配置文件 syslog.conf 中的 level 對應。
LOG_EMERG | 緊急情況 |
---|---|
LOG_ALERT | 應該被立即改正的問題,如系統數據庫破壞 |
LOG_CRIT | 重要情況,如硬盤錯誤 |
LOG_ERR | 錯誤 |
LOG_WARNING | 警告信息 |
LOG_NOTICE | 不是錯誤情況,但是可能需要處理 |
LOG_INFO | 情報錯誤 |
LOG_DEBUG | 包含情報的信息,通常指在調試一個程序時使用 |
-
closelog函數(關閉當前打開日誌系統)
函數說明:關閉日誌設備,與文件系統調用的close類似;調用closelog也是可選擇的,它只是關閉被用於與syslog守護進程通信的描述符。
-
編程示例
#ifndef __DAEMON_H__
#define __DAEMON_H__
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <syslog.h>
#include <libgen.h>
#endif
int main (int argc, char *argv[])
{
char *progname = basename(argv[0]);
if( daemon(1,1) < 0)
{
printf("Program daemon failure:%s\n", strerror(errno));
return -1;
}
openlog("daemon",LOG_CONS | LOG_PID,0); //打開日誌系統
syslog(LOG_NOTICE, "program '%s' start running\n",progname); //寫入日誌信息
syslog(LOG_WARNING, "program '%s' running with a warnning message\n", progname);
syslog(LOG_EMERG, "program '%s' running with a emergency message\n",progname);
while (1)
{
//do something;
}
syslog(LOG_NOTICE, "program '%s' stop running\n", progname);
closelog(); //關閉日誌系統
return 0;
}
- 我們可以在使用以下命令來查看寫入到系統日誌的信息,
vim /var/log/syslog
-
運行程序寫入日誌系統的內容(由於Linux 實行的時日誌回滾系統,我們寫入的信息一般在最後)