1. 程式人生 > >關於精靈程序的一些思考和程式碼片段

關於精靈程序的一些思考和程式碼片段



設定精靈程序


static void set_daemon(void)

{

       pit_t pid;

       int     fd;

       pid = fork();

       if(pid < 0)

      {

            log_error("Set daemon error!);

            exit(-1);

      }

     else if( pid > 0)

     {

             exit(0);

      }

     fd  = open("/dev/null".O_RDWR);

     /* we want close stdin stdou*/

    {

          close(0);

          close(1);

          dup(fd);

          dup(fd);

          close(fd);

     }    

    setsid();

    pid = fork();

    if( pid<0)

   {

       log_error("Set: daemon error");

       exit(-1);

   }

    else if(pid > 0)

    {

         exit(0);

    }

}


其中,最重要的一個函式呼叫是setsid,目的是建立一個新對話期。使呼叫程序:

(a)成為新對話期的首程序

(b)成為一個新程序組的首程序

(c)沒有控制終端
   這裡面有三個概念:程序組、會話期與控制終端,下面分別闡述。


程序組:

程序組的概念是因管道符而生。
用管道符連線的程序都在同一個程序組裡,例如:
ps -xj | cat1 | cat2
如果想殺掉所有相關程序,就必須引入程序組的概念。以下是kill呼叫的方法:
int kill(pid_t pid, int signo);
pid==0 將訊號傳送給其程序組I D等於傳送程序的程序組I D,而且傳送程序有許可權向
其傳送訊號的所有程序。
pid<0 將訊號傳送給其程序組I D等於p i d絕對值,而且傳送程序有許可權向其傳送訊號
的所有程序。


引入會話期與控制終端的意義:
會話期與控制終端的概念是因後臺程序而生。
例如:tail -f log.file &
該程序不接收退出訊號(ctrl + C),並且在使用者退出登陸後依然存在,這種程序我們稱為後臺程序,後臺程序的實現需要引入會話期與控制終端的概念。

以下是會話期和控制終端的描述:
1.對話期可以包括多個程序組。
2.一個對話期可以有一個單獨的控制終端( controlling terminal)。這通常是我們在其上登入的終端裝置(終端登入情況)或偽終端裝置(網路登入情況)。
3.一個對話期中的幾個程序組可被分成一個前臺程序組( foreground process group)以及一個或幾個後臺程序組(background process group)
如果一個對話期有一個控制終端,則它有一個前臺程序組,其他程序組則為後臺程序組。
4.無論何時鍵入中斷鍵(常常是D E L E T E或C t r l - C)或退出鍵(常常是C t r l - \),就會造成將中斷訊號或退出訊號送至前臺程序組的所有程序。   setsid的用法
程序呼叫setsid函式就可建立一個新對話期。
如果呼叫此函式的程序不是一個程序組的組長,則此函式建立一個新對話期,結果為:
(1) 此程序變成該新對話期的對話期首程序(session leader,對話期首程序是建立該對話期的程序)。此程序是該新對話期中的唯一程序。
(2) 此程序成為一個新程序組的組長程序。新程序組id是此呼叫程序的程序ID。
(3) 此程序沒有控制終端(下一節討論控制終端)。如果在呼叫setsid之前此程序有一個控
制終端,那麼這種聯絡也被解除。
如果此呼叫程序已經是一個程序組的組長,則此函式返回出錯。為了保證不處於這種情況,
通常先呼叫fork,然後使其父程序終止,而子程序則繼續。因為子程序繼承了父程序的程序組ID,而其程序ID則是新分配的,兩者不可能相等,所以這就保證了子程序不是一個程序組的組長。


1、首先呼叫fork,然後使父程序exit. 2、呼叫setsid以建立一個新的會話。 3、呼叫chdir將工作目錄改為根目錄。 4、將檔案方式建立遮蔽字設為0.(umask(0);) 5、關閉不需要的檔案描述字。

精靈程序退出處理


當用戶需要外部停止守護程序執行時,往往會使用 kill命令停止該守護程序。所以,守護程序中需要

編碼來實現kill發出的signal訊號處理,達到程序的正常退出


signal(SIGTERM, sigterm_handler); void sigterm_handler(int arg) { _running = 0; } =============================== 這樣,一個簡單的守護程序就建立起來了。 實現守護程序的完整例項(每隔10s在/tmp/dameon.log中寫入一句話):