[Linux] 守護進程和守護線程

來源:互聯網
上載者:User

標籤:style   blog   http   color   java   使用   os   io   

對於JAVA而言,一般一個應用程式只有一個進程——JVM。除非在代碼裡面另外派生或者開啟了新進程。

而線程,當然是由進程開啟的。當開啟該線程的進程離開時,線程也就不複存在了。

所以,對於JAVA而言,線程是完全可以由自己的API自由產生。例如new Thread().但是進程就不同,必須通過調用OS的API,如Runtime.getRuntime.exec()。 所以說,進程是OS層級的概念。

守護線程和使用者線程的區別:

二者其實基本上是一樣的。唯一的區別在於JVM何時離開。

使用者線程:當存在任何一個使用者線程未離開,JVM是不會離開的。

守護線程:如果只剩下守護線程未離開,JVM是可以離開的。

在Java中,製作守護線程非常簡單,直接利用.setDaemon(true)

在linux或者unix作業系統中在系統的引導的時候會開啟很多服務,這些服務就叫做守護進程。為了增加靈活性,root可以選擇系統開啟的模式,這些模式叫做運行層級,每一種運行層級以一定的方式配置系統。 守護進程是脫離於終端並且在後台啟動並執行進程。守護進程脫離於終端是為了避免進程在執行過程中的資訊在任何終端上顯示並且進程也不會被任何終端所產生的終端資訊所打斷。

守護進程簡介  守護進程,也就是通常說的Daemon進程,是Linux中的後台服 務進程。它是一個生存期較長的進程,通常獨立於控制終端並且周期性地執行某種任務或等待處理某些發生的事件。守護進程常常在系統引導裝入時啟動,在系統關 閉時終止。Linux系統有很多守護進程,大多數服務都是通過守護進程實現的,同時,守護進程還能完成許多系統任務,例如,作業規划進程crond、列印 進程lqd等(這裡的結尾字母d就是Daemon的意思)。

  由於在Linux中,每一個系統與使用者進行交流的介面稱為終端,每一個從此終端開始啟動並執行進程都會依附於這個終端,這個終端就稱為這些進程的控 制終端,當控制終端被關閉時,相應的進程都會自動關閉。但是守護進程卻能夠突破這種限制,它從被執行開始運轉,直到整個系統關閉時才退出。如果想讓某個進 程不因為使用者或終端或其他地變化而受到影響,那麼就必須把這個進程變成一個守護進程。

建立守護進程 建立子進程,父進程退出

  這是編寫守護進程的第一步。由於守護進程是脫離控制終端的,因此,完成第一步後就會在Shell終端裡造成一程式已經運行完畢的假象。之後的所有工作都在子進程中完成,而使用者在Shell終端裡則可以執行其他命令,從而在形式上做到了與控制終端的脫離。

  在Linux中父進程先於子進程退出會造成子進程成為孤兒進程,而每當系統發現一個孤兒進程時,就會自動由1號進程(init)收養它,這樣,原先的子進程就會變成init進程的子進程。

在子進程中建立新會話

  這個步驟是建立守護進程中最重要的一步,雖然它的實現非常簡單,但它的意義卻非常重大。在這裡使用的是系統函數setsid,在具體介紹setsid之前,首先要瞭解兩個概念:進程組和會話期

  進程組:是一個或多個進程的集合。進程組有進程組ID來唯一標識。除了進程號(PID)之外,進程組ID也是一個進程的必備屬性。每個進程組都有一個組長進程,其組長進程的進程號等於進程組ID。且該進程組ID不會因組長進程的退出而受到影響。

  會話周期:會話期是一個或多個進程組的集合。通常,一個會話開始於使用者登入,終止於使用者退出,在此期間該使用者啟動並執行所有進程都屬於這個會話期。

  接下來就可以具體介紹setsid的相關內容:

  (1)setsid函數作用:

  setsid函數用於建立一個新的會話,並擔任該交談群組的組長。調用setsid有下面的3個作用:

  讓進程擺脫原會話的控制

  讓進程擺脫原進程組的控制

  讓進程擺脫原控制終端的控制

  那麼,在建立守護進程時為什麼要調用setsid函數呢?由於建立守護進程的第一步調用了fork函數來建立子進程,再將父進程退出。由於在調用了fork函數時,子進程全盤拷貝了父進程的會話期、進程組、控制終端等,雖然父進程退出了,但會話期、進程組、控制終端等並沒有改變,因此,這還不是真正意義上的獨立開來,而setsid函數能夠使進程完全獨立出來,從而擺脫其他進程的控制。

改變目前的目錄為根目錄

  這一步也是必要的步驟。使用fork建立的子進程繼承了父進程的當前工作目錄。由於在進程運行中,目前的目錄所在的檔案系統(如“/mnt/usb”)是不能卸載的, 這對以後的使用會造成諸多的麻煩(比如系統由於某種原因要進入單一使用者模式)。因此,通常的做法是讓"/"作為守護進程的當前工作目錄,這樣就可以避免上述 的問題,當然,如有特殊需要,也可以把當前工作目錄換成其他的路徑,如/tmp。改變工作目錄的常見函數式chdir。

重設檔案許可權掩碼

  檔案許可權掩碼是指屏蔽掉檔案許可權中的對應位。比如,有個檔案許可權掩碼是050,它就屏蔽了檔案組擁有者的可讀與可執行許可權。由於使用fork函數建立的子進程繼承了父進程的檔案許可權掩碼,這就給該子進程使用檔案帶來了諸多的麻煩。因此,把檔案許可權掩碼設定為0,可以大大增強該守護進程的靈活性。設定檔案許可權掩碼的函數是umask。在這裡,通常的使用方法為umask(0)。

關閉檔案描述符

  同檔案許可權碼一樣,用fork函數建立的子進程會從父進程那裡繼承一些已經開啟了的檔案。這些被開啟的檔案可能永遠不會被守護進程讀寫,但它們一樣消耗系統資源,而且可能導致所在的檔案系統無法卸下。

  在上面的第二步之後,守護進程已經與所屬的控制終端失去了聯絡。因此從終端輸入的字元不可能達到守護進程,守護進程中用常規方法(如printf)輸出的字元也不可能在終端上顯示出來。所以,檔案描述符為0、1和2 的3個檔案(常說的輸入、輸出和報錯)已經失去了存在的價值,也應被關閉。通常按如下方式關閉檔案描述符:

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

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

  close(i);

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

守護進程退出處理

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

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

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

  signal(SIGTERM, sigterm_handler);

  void sigterm_handler(int arg)

  {

  _running = 0;

  }

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

  這樣,一個簡單的守護進程就建立起來了。

  實現守護進程的完整執行個體(每隔10s在/tmp/dameon.log中寫入一句話):

#include<stdio.h>  #include<stdlib.h>  #include<string.h>  #include<fcntl.h>  #include<sys/types.h>  #include<unistd.h>  #include<sys/wait.h>  #include <signal.h>  #define MAXFILE 65535  volatile sig_atomic_t _running = 1;  int main()  {  pid_t pc;  int i,fd,len;  char *buf="this is a Dameon\n";  len = strlen(buf);  pc = fork(); //第一步  if(pc<0){  printf("error fork\n");  exit(1);  }  else if(PC>0)  exit(0);  setsid(); //第二步  chdir("/"); //第三步  umask(0); //第四步  for(i=0;i<MAXFILE;i++) //第五步  close(i);  signal(SIGTERM, sigterm_handler);  while( _running ){  if((fd=open("/tmp/dameon.log",O_CREAT|O_WRONLY|O_APPEND,0600))<0){  perror("open");  exit(1);  }  write(fd,buf,len);  close(fd);  usleep(10*1000); //10毫秒  }  }  void sigterm_handler(int arg)  {  _running = 0;  }
linux守護進程列表

amd:自動安裝NFS(網路檔案系統)守侯進程

  apmd:進階電源治理

  Arpwatch:記錄日誌並構建一個在LAN介面上看到的乙太網路地址和ip地址對資料庫

  Autofs:自動安裝治理進程automount,與NFS相關,依靠於NIS

  Bootparamd:引導參數伺服器,為LAN上的無盤工作站提供引導所需的相關資訊

  crond:linux下的計劃任務

  Dhcpd:啟動一個DHCP(動態IP地址分配)伺服器

  Gated:網關路由守候進程,使用動態OSPF路由選擇協議

  Httpd:WEB伺服器

  Inetd:支援多種網路服務的核心守候程式

  Innd:Usenet新聞伺服器

  Linuxconf:答應使用本地WEB伺服器作為使用者介面來配置機器

  Lpd:列印伺服器

  Mars-nwe:mars-nwe檔案和用於Novell的列印伺服器

  Mcserv:Midnight命令檔案伺服器

  named:DNS伺服器

  netfs:安裝NFS、Samba和NetWare網路檔案系統

  network:啟用已配置網路介面的指令碼程式

  nfs:開啟NFS服務

  nscd:nscd(Name Switch Cache daemon)伺服器,用於NIS的一個支援服務,它快取使用者口令和組成成員關係

  portmap:RPC portmap治理器,與inetd類似,它治理基於RPC服務的串連

  postgresql:一種SQL資料庫伺服器

  routed:路由守候進程,使用動態RIP路由選擇協議

  rstatd:一個為LAN上的其它機器收集和提供系統資訊的守候程式

  ruserd:遠端使用者定位服務,這是一個基於RPC的服務,它提供關於目前記錄到LAN上一個機器日誌中的使用者資訊

  rwalld:啟用rpc.rwall服務進程,這是一項基於RPC的服務,答應使用者給每個註冊到LAN機器上的其他終端寫訊息

  rwhod:啟用rwhod服務進程,它支援LAN的rwho和ruptime服務

  sendmail:郵件伺服器sendmail

  smb:Samba檔案分享權限設定/列印服務

  snmpd:本地簡單網路治理候進程

  squid:啟用Proxy 伺服器squid

  syslog:一個讓系統引導時起動syslog和klogd系統日誌守候進程的指令碼

  xfs:X Window字型伺服器,為本地和遠程X伺服器提供字型集

  xntpd:網路時間伺服器

  ypbind:為NIS(網路資訊系統)客戶機啟用ypbind服務進程

  yppasswdd:NIS口令伺服器

  ypserv:NIS主伺服器

  gpm:管滑鼠的

  identd:AUTH服務,在提供使用者資訊方面與finger類似

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.