1. 程式人生 > >Linux C 守護程序實現後臺執行nohup效果

Linux C 守護程序實現後臺執行nohup效果

守護程序(Daemon)是執行在後臺的一種特殊程序。它獨立於控制終端並且週期性地執行某種任務或等待處理某些發生的事件。守護程序是一種很有用的進 程。Linux的大多數伺服器就是用守護程序實現的。比如,Internet伺服器inetd,Web伺服器httpd等。同時,守護程序完成許多系統任 務。比如,作業規劃程序crond,列印程序lpd等。

      守護程序的程式設計本身並不複雜,複雜的是各種版本的Unix的實現機制不盡相同,造成不同Unix環境下守護程序的程式設計規則並不一致。這需要讀者注意,照搬 某些書上的規則(特別是BSD4.3和低版本的System V)到Linux會出現錯誤的。下面將全面介紹Linux下守護程序的程式設計要點並給出詳細例項。

一. 守護程序及其特性 
      守護程序最重要的特性是後臺執行。在這一點上DOS下的常駐記憶體程式TSR與之相似。其次,守護程序必須與其執行前的環境隔離開來。這些環境包括未關閉的 檔案描述符,控制終端,會話和程序組,工作目錄以及檔案建立掩模等。這些環境通常是守護程序從執行它的父程序(特別是shell)中繼承下來的。最後,守 護程序的啟動方式有其特殊之處。它可以在Linux系統啟動時從啟動指令碼/etc/rc.d中啟動,可以由作業規劃程序crond啟動,還可以由使用者終端 (通常是shell)執行。

      總之,除開這些特殊性以外,守護程序與普通程序基本上沒有什麼區別。因此,編寫守護程序實際上是把一個普通程序按照上述的守護程序的特性改造成為守護程序。如果讀者對程序有比較深入的認識就更容易理解和程式設計了。

二. 守護程序的程式設計要點 
      前面講過,不同Unix環境下守護程序的程式設計規則並不一致。所幸的是守護程序的程式設計原則其實都一樣,區別在於具體的實現細節不同。這個原則就是要滿足守護 程序的特性。同時,Linux是基於Syetem V的SVR4並遵循Posix標準,實現起來與BSD4相比更方便。程式設計要點如下:
1. 在後臺執行
      為避免掛起控制終端將Daemon放入後臺執行。方法是在程序中呼叫fork使父程序終止,讓Daemon在子程序中後臺執行。 
if(pid=fork()) 

exit(0);//是父程序,結束父程序,子程序繼續

2. 脫離控制終端,登入會話和程序組 

      有必要先介紹一下Linux中的程序與控制終端,登入會話和程序組之間的關係:程序屬於一個程序組,程序組號(GID)就是程序組長的程序號(PID)。登入會話可以包含多個程序組。這些程序組共享一個控制終端。這個控制終端通常是建立程序的登入終端。
控制終端,登入會話和程序組通常是從父程序繼承下來的。我們的目的就是要擺脫它們,使之不受它們的影響。方法是在第1點的基礎上,呼叫setsid()使程序成為會話組長:
setsid(); 

      說明:當程序是會話組長時setsid()呼叫失敗。但第一點已經保證程序不是會話組長。setsid()呼叫成功後,程序成為新的會話組長和新的程序組長,並與原來的登入會話和程序組脫離。由於會話過程對控制終端的獨佔性,程序同時與控制終端脫離。

3. 禁止程序重新開啟控制終端 
      現在,程序已經成為無終端的會話組長。但它可以重新申請開啟一個控制終端。可以通過使程序不再成為會話組長來禁止程序重新開啟控制終端: 
if(pid=fork()) 

exit(0);//結束第一子程序,第二子程序繼續(第二子程序不再是會話組長) 

4. 關閉開啟的檔案描述符 
      程序從建立它的父程序那裡繼承了開啟的檔案描述符。如不關閉,將會浪費系統資源,造成程序所在的檔案系統無法卸下以及引起無法預料的錯誤。按如下方法關閉它們:
for(i=0;i 關閉開啟的檔案描述符close(i);> 

for(i=0;i< NOFILE;++i)

5. 改變當前工作目錄 

      程序活動時,其工作目錄所在的檔案系統不能卸下。一般需要將工作目錄改變到根目錄。對於需要轉儲核心,寫執行日誌的程序將工作目錄改變到特定目錄如/tmpchdir("/")

6. 重設檔案建立掩模 

      程序從建立它的父程序那裡繼承了檔案建立掩模。它可能修改守護程序所建立的檔案的存取位。為防止這一點,將檔案建立掩模清除:umask(0); 

7. 處理SIGCHLD訊號 
      處理SIGCHLD訊號並不是必須的。但對於某些程序,特別是伺服器程序往往在請求到來時生成子程序處理請求。如果父程序不等待子程序結束,子程序將成為 殭屍程序(zombie)從而佔用系統資源。如果父程序等待子程序結束,將增加父程序的負擔,影響伺服器程序的併發效能。在Linux下可以簡單地將 SIGCHLD訊號的操作設為SIG_IGN。
signal(SIGCHLD,SIG_IGN); 

      這樣,核心在子程序結束時不會產生殭屍程序。這一點與BSD4不同,BSD4下必須顯式等待子程序結束才能釋放殭屍程序。 

三. 守護程序例項 

      守護程序例項包括兩部分:主程式test.c和初始化程式init.c。主程式每隔一分鐘向/tmp目錄中的日誌test.log報告執行狀態。初始化程式中的init_daemon函式負責生成守護程序。讀者可以利用init_daemon函式生成自己的守護程序。

1. init.c清單 
  1. #include < unistd.h > 
  2. #include < signal.h > 
  3. #include < sys/param.h > 
  4. #include < sys/types.h > 
  5. #include < sys/stat.h > 
  6. void init_daemon(void)   
  7. {   
  8. int pid;   
  9. int i;   
  10. if(pid=fork())   
  11. exit(0);//是父程序,結束父程序 
  12. elseif(pid< 0)   
  13. exit(1);//fork失敗,退出 
  14. //是第一子程序,後臺繼續執行 
  15. setsid();//第一子程序成為新的會話組長和程序組長 
  16. //並與控制終端分離 
  17. if(pid=fork())   
  18. exit(0);//是第一子程序,結束第一子程序 
  19. elseif(pid< 0)   
  20. exit(1);//fork失敗,退出 
  21. //是第二子程序,繼續 
  22. //第二子程序不再是會話組長 
  23. for(i=0;i< NOFILE;++i)//關閉開啟的檔案描述符 
  24. close(i);   
  25. chdir("/tmp");//改變工作目錄到/tmp 
  26. umask(0);//重設檔案建立掩模 
  27. return;   
  28. }  

2. test.c清單 

  1. #include < stdio.h > 
  2. #include < time.h > 
  3. void init_daemon(void);//守護程序初始化函式 
  4. main()   
  5. {   
  6. FILE *fp;   
  7. time_t t;   
  8. init_daemon();//初始化為Daemon 
  9. while(1)//每隔一分鐘向test.log報告執行狀態 
  10. {   
  11. sleep(60);//睡眠一分鐘 
  12. if((fp=fopen("test.log","a")) >=0)   
  13. {   
  14. t=time(0);   
  15. fprintf(fp,"I'm here at %sn",asctime(localtime(&t)) );   
  16. fclose(fp);   
  17. }   
  18. }   
  19. }  

      以上程式在RedHat Linux6.0下編譯通過。步驟如下:

1)編譯:gcc –g –o test init.c test.c 
2)執行:./test 
3)檢視程序:ps –ef 

      從輸出可以發現test守護程序的各種特性滿足上面的要求。

相關推薦

Linux C 守護程序實現後臺執行nohup效果

守護程序(Daemon)是執行在後臺的一種特殊程序。它獨立於控制終端並且週期性地執行某種任務或等待處理某些發生的事件。守護程序是一種很有用的進 程。Linux的大多數伺服器就是用守護程序實現的。比如,Internet伺服器inetd,Web伺服器httpd等。同時,守護

用PHP實現守護程序任務後臺執行與多執行緒(php-resque使用說明)

訊息佇列處理後臺任務帶來的問題 專案中經常會有後臺執行任務的需求,比如傳送郵件時,因為要連線郵件伺服器,往往需要5-10秒甚至更長時間,如果能先給使用者一個成功的提示資訊,然後在後臺慢慢處理髮送郵件的操作,顯然會有更好的使用者體驗。 為了實現類似的需求,We

在Ubuntu下安裝nodejs4.x,並實現開機自動啟動forever程序守護nodejs應用後臺執行

一、在Ubuntu下安裝nodejs4.x 官方文件的方法最簡單,不會出錯 Node.js v4.x: NOTE: If you are using Ubuntu Precise or Debian Wheezy, you might want to read a

Java程式在Linux實現後臺執行

1、執行指令碼 程式的目錄結構如下 [[email protected] SocketDxpTaxi]# ls config lib logs run.sh SocketDxpTaxi.jar [[email protected]

AIX, Linux下將指令碼放到後臺執行——加nohup與不加nohup的區別

對於Linux下來說,當在系統上執行下面的命令,將test.sh指令碼放到後臺執行/location/test.sh &此時,分兩種情況考慮問題,一:繼續執行exit命令退出當前session, 則 test.sh這個指令碼仍然在Linux系統裡面執行,二:不執行e

Linux後臺執行 nohup command >/dev/null 2>&1 &

Linux shell中有三種輸入輸出,分別為標準輸入,標準輸出,錯誤輸出,分別對應0,1,2。我們可以直接通過輸出重定向>(或>>,表示追加)將某種輸出重定向到其他地方,如裝置,檔案,比如: 1 ls > ls.log  #標準輸出重定向

使用 nohup程序後臺執行

1. & 啟動的程序在終端關閉之後也會被關閉比如作者寫了一個 java 程式 rainbow-app2-1.0.0.jar,使用以下命令啟動# java -jar rainbow-app2-1.0.0.jar &一個程序被啟動,並且在後臺運行了。通過 ps 檢

linux在如何讓程序後臺執行

今天碰到這麼一個問題,使用ssh客戶端登陸了linux伺服器,啟動並執行服務之後如果關閉客戶端與伺服器的連線,這個時候運行於伺服器上的服務也會被關閉,如何讓命令提交之後不受本地關閉終端埠的影響呢? 首先我們要知道為啥客戶端的斷開會影響服務端程式的執行? 當用戶登出或

linux守護程序、SIGHUP與nohup詳解

前端時間幫忙定位個問題。docker容器故障恢復後,其中的keepalived程序始終無法啟動,也看不到Keepalived的日誌。 strace 檢視系統呼叫之後,發現了原因所在 1 socket(PF_LOCAL, SOCK_DGRAM|SOCK_CLOEXEC,

後臺守護程序實現coredump

1.在/etc/profile中加入以下一行,這將允許生成coredump檔案 ulimit-c unlimited 2. 在rc.local中加入以下一行,這將使程式崩潰時生成的coredump檔案位於/data/coredump/目錄下: echo "/bin/esun

Linux守護程序以及實現一個守護程序

1、什麼是守護程序 守護程序也稱為精靈程序,是執行在後臺程序的一種特殊程序。它獨立於控制終端並且週期性地執行某種任務或等待處理某些發生的事件。 (1)脫離於控制終端並且在後臺執行 (2)不受使用者登入登出的影響,它們一直在執行著 Linux大多數伺服器就

使用linux-c編程實現簡單的ls命令

使用c實現ls命令使用Linux—c編程實現簡單的ls命令 具體代碼如下: 加載的頭文件有stdio.h,sys/types.h,dirent.h,unistd.h,sys/stat.h,fcntl.h,string.h等。 void main(int argc,char **argv){

C#獲取程序代碼執行時長

using csharp edt lis blog 程序 end 程序代碼 mil ArrayList list = new ArrayList(); long startTicks = DateTime.Now.Ticks

cp&tar&用c語言編寫程序 實現cp命令的效果

none des tdi 文件內容 display 我們 class pan fop 1.cp (拷貝) 已存在文件路徑 要拷貝的文件路徑 實現cp命令的代碼如下: 2 #include <stdio.h>

12-後臺執行 - nohup ./sh &

spa back color out ack round fff 執行 .sh $ nohup ./gsj.sh & 或者$ nohup ./gsj.sh & > name.out12-後臺執行 - nohup ./sh &

Linux程式設計 多程序,多執行緒求解PI(圓周率)

題目: 連結 多程序: #include <unistd.h> #include <stdio.h> #include <stdlib.h> #define n 100000000.0 int main() { i

Linux】多程序與多執行緒之間的區別

http://blog.csdn.net/byrsongqq/article/details/6339240 網路程式設計中設計併發伺服器,使用多程序與多執行緒 ,請問有什麼區別?  答案一: 1,程序:子程序是父程序的複製品。子程序獲得父程序資料空間、堆和棧的複製品。 2,執行緒:相

linux中啟動 java -jar 後臺執行程式 linux中啟動 java -jar 後臺執行程式

ps -ef | grep java  查詢java 端口占用   linux中啟動 java -jar 後臺執行程式   直接用java -jar xxx.jar,當退出或關閉shell時,程式就會停止掉。以下方法可讓jar執行後一直在後臺執行。

Linux C程式設計--程序介紹3--程序終止和等待

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

Java併發(十八):阻塞佇列BlockingQueue BlockingQueue(阻塞佇列)詳解 二叉堆(一)之 圖文解析 和 C語言的實現執行緒程式設計:阻塞、併發佇列的使用總結 Java併發程式設計:阻塞佇列 java阻塞佇列 BlockingQueue(阻塞佇列)詳解

阻塞佇列(BlockingQueue)是一個支援兩個附加操作的佇列。 這兩個附加的操作是:在佇列為空時,獲取元素的執行緒會等待佇列變為非空。當佇列滿時,儲存元素的執行緒會等待佇列可用。 阻塞佇列常用於生產者和消費者的場景,生產者是往佇列裡新增元素的執行緒,消費者是從佇列裡拿元素的執行緒。阻塞佇列就是生產者