[Linux]守護進程(精靈進程)

一、守護進程是什么

守護進程是生存期很長的一種進程,可以說它是7*24小時工作的。(什么是7*24,一周7天,每天24小時,這不就是一年365天一直在工作嘛,還搞的這么詼諧,哈哈)。它們常常在系統引導裝入時啟動,僅在系統關閉時才終止。因為它們沒有控制終端,所以說它們是在后臺運行的,而且它沒法直接和用戶交互。當然在后臺運行的可不一定是守護進程哦。Unix下有很多守護進程,執行日常事務。守護進程是一種很有用的進程,Linux下的很多服務器大多是用守護進程實現的。比如Internet服務器inetd,Web服務器httpd等。

守護進程還有一個特點:其它進程都是在用戶登錄或運行程序時創建,在運行結束或用戶注銷時終止,但系統服務進程不受用戶登錄注銷的影響,它們一直在運行著。

我們用ps -axj來查看系統中的進程。-a顯示由其他用戶所擁有的進程的狀態,-x顯示沒有控制終端的進程,-j顯示與作業有關的信息(進程組ID,會話ID,控制終端,終端進程組ID)。守護進程通常以d為結尾。

這里寫圖片描述

由上述的進程中,TPGID為-1的都是沒有控制終端的進程,也是守護進程。還有像COMMAND那一列中,用[]括起來的進程名,都表示內核線程。這些線程在內核里創建,沒有用戶空間代碼,因此沒有程序文件名和命令行,以k開頭,表示Kernel。它自成進程組,自成會話。

進程1通常是init,它是一個系統守護進程。

二、創建守護進程

我們寫一個mydaemon:

步驟哈:1.創建守護進程首先得,調用umask來將文件模式創建屏蔽字設置為0。

2.調用fork,使父進程退出。因為在這里,后面使用setid不允許進程為進程組id,因此得先將父進程exit。

3.調用setid創建一個新會話,成為會話首進程,成為進程組組長,沒有控制終端。這就是守護進程的特點吧。

4.將當前的工作目錄改為根目錄。你想想,如果你將守護進程的工作目錄設置為當前工作目錄而非根目錄,那么如果將這個目錄刪除后,就會導致嚴重的丟失問題。你的那個目錄將不能被刪除。

5.關閉不再需要的文件描述符。

守護進程實現:

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<signal.h>
void mydaemon()
{umask(0);if(fork() <=  0)//child{}else//father{exit(0);}setsid();signal(SIGCHLD,SIG_IGN);close(0);close(1);close(2);chdir("/");}int main()
{mydaemon();
//  daemon(0,0);while(1);return 0;
}

運行結果:

這里寫圖片描述

這樣一個守護進程就寫好啦。當然庫里邊也實現了一個守護進程,daemon函數。

int daemon(int nochdir, int noclose);

這里nochdir表示不改變當前守護進程的目錄,noclose表示不關閉進程文件描述符。

當前我們是把工作目錄修改了,所以:

這里寫圖片描述

當我們都設置為0時,daemon(0,0);說明修改; 當我們都設置為1時,daemon(1,1);說明不修改;

三、為什么創建守護進程時有人fork兩次?

第二次fork的作用:雖然當前關閉了和終端的聯系,但是后期可能會誤操作打開了終端。只有會話首進程能打開終端設備,也就是再fork一次,再把父進程退出,再次fork的子進程作為守護進程繼續運行,保證了該精靈進程不是會話的首進程,第二次不是必須的,是可選的,市面上有些開源項目也是fork一次。(再次fork一次,保證daemon進程,之后不會打開tty設備)

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/382686.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/382686.shtml
英文地址,請注明出處:http://en.pswp.cn/news/382686.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

linux命令行界面下ctrl 常用組合鍵速查表

Ctrlz 暫停正在運行的程序 Ctrll 清屏 Ctrld 結束輸入或退出shell Ctrla 切換到命令行開始 Ctrle 切換到命令行末尾 Ctrlu 刪除光標前內容 Ctrlk 刪除光標后內容 Ctrlxu 撤銷操作

[Linux]運輸層的端口

既然提到端口&#xff0c;我們就來分析一下為什么要使用端口的緣由吧。我們首先要知道的是&#xff0c;運輸層有復用和分用的功能。應用層所有的應用進程都可以通過運輸層再傳送到IP層&#xff0c;這就是復用。運輸層從IP層收到數據后必須交付到指明的應用進程&#xff0c;這就…

淺談shell中的clear命令實現

NAME(名稱) clear - 清除終端屏幕 SYNOPSIS(總覽) clear DESCRIPTION(描述) clear可以在允許的情況下清屏. 它會在環境變量中查找終端的類型, 然后到terminfo數據庫中找出清屏的方法. 《man手冊》 #include <stdio.h>int clear_main(int argc, char **argv) {/* Th…

C++ 對引用的理解

引用可以看做是數據的一個別名&#xff0c;通過這個別名和原來的名字都能夠找到這份數據引用必須在定義的同時初始化&#xff0c;并且以后也要從一而終&#xff0c;不能再引用其它數據&#xff0c;這有點類似于常量&#xff08;const 變量&#xff09;。引用變量 里面 實際存儲…

[Linux]ARP協議

概念&#xff1a; 1. ARP協議(地址解析協議):由IP地址轉換為MAC地址的協議。IP地址&#xff1a;網絡號主機號。MAC地址&#xff1a;數據鏈路層的物理地址&#xff08;硬件地址&#xff09;。IP協議使用了ARP協議&#xff0c;因此被劃歸為網絡層&#xff0c;但其用途是從網絡層…

Makefile使用及多文件gdb 調試

文件內容 [koulocalhost makefile]$ cat 1.c #include "3.h" int main() {key_t key ftok(".",1);printf("%d\n",add(1,2));return 0; }[koulocalhost makefile]$ cat 2.c #include "3.h" int add(int a, int b) {return a b; } [k…

C++ 對引用的理解2

1.指針就是數據或代碼在內存中的地址&#xff0c;指針變量指向的就是內存中的數據或代碼。這里有一個關鍵詞需要強調&#xff0c;就是內存&#xff0c;指針只能指向內存&#xff0c;不能指向寄存器或者硬盤&#xff0c;因為寄存器和硬盤沒法尋址。 2.其實 C 代碼中的大部分內容…

Ubuntu各版本主要差異

Ubuntu各版本主要差異 (重定向自Ubuntu &#xff0c; kubuntu與xubuntu的差別 ) Ubuntu官方考慮到使用者的不同需求&#xff0c;提供各種不同的發行版。這幾種發行版本的差別在于桌面環境和預設安裝的軟體不同&#xff0c;但套件庫是采用一樣的&#xff0c;所以您當然可以在安…

[Linux]CRC校驗

CRC(Cyclic Redundancy Check),循環冗余校驗碼&#xff0c;是數據通信領域中最常用的一種差錯校驗碼&#xff0c;其特征是信息字段和校驗字段的長度可以任意選定。 CRC校驗步驟&#xff1a; CRC分為兩部分&#xff0c;前部分為信息碼&#xff0c;后部分為校驗碼&#xff1b;設…

visual studio 2015 配置好qt5后, 第一次運行出現 無法打開源文件“QtWidgets/QApplication”和無法運行rc.exe的解決方案

無法打開源文件“QtWidgets/QApplication” a.在工程中右擊項目&#xff0c;點擊屬性。 b.選擇VC目錄->包含目錄 c.選擇Qt安裝目錄中的頭文件包含目錄&#xff0c;一般為Qt版本號/版本號/編譯器名/include 比如&#xff1a;E:\Qt\Qt5.6.3\5.6.3\msvc2015\include 在C\C>附…

怎么在vs中查看一個數組的所有元素

在監視窗口&#xff0c;我們想要查看所有的數組元素。 這個時候 int arr[] {1,2,3} arr只顯示1 正確的方法 arr&#xff0c;10

[Linux]NAT和代理服務器

1. NAT&#xff1a;&#xff08;Network Address Translation&#xff09;是網絡地址轉換。 我們有這樣一種場景&#xff0c;在專用網內部的一些主機本來已經分配到了本地IP地址&#xff0c;但現在又想和因特網上的主機通信&#xff0c;我們可以設法再申請一些全球IP地址&…

使用 C++的第三方庫 jsoncpp的步驟以及出現的問題

Jsoncpp 是一個json解析庫 下載地址為&#xff1a; http://sourceforge.net/projects/jsoncpp/ 方法一&#xff1a;使用Jsoncpp生成的lib文件 解壓上面下載的Jsoncpp文件&#xff0c;在jsoncpp-src-0.5.0/makefiles/vs71目錄里找到jsoncpp.sln&#xff0c;用VS2008版本編譯&am…

常用的友元重載運算符OSTREAM

對<<運算符重載&#xff0c;讓他能和cout一起顯示對象內容。 顯示值可以使用show()&#xff0c;但是使用cout<<更方便。 ostream類對該運算符進行了重載&#xff0c;將其轉換成輸出工具。 cout就是一個ostream的對象&#xff0c;他可以自動識別所有的c基本類型。…

python字符串系列

1.find方法用于在長串中查找子串&#xff0c;返回子串中最左位置的下標&#xff0c;如果沒找到&#xff0c;則返回-1 2.join方法用于在隊列中添加元素 3.lower返回字符串的小寫字母版 4.replace返回字符串中所有匹配項均被替換之后得到字符串 5.split將字符串分割成序列 6.stri…

C++ wstring 與 string 之間的相互轉換.

方式一&#xff1a;調用Windows API #include <Windows.h> //將string轉換成wstring wstring string2wstring(string str) { wstring result; //獲取緩沖區大小&#xff0c;并申請空間&#xff0c;緩沖區大小按字符計算 int len MultiByteToWideChar(CP_ACP, 0,…

linux網絡編程Internet Socket地址,套接字,和函數

文章內容節選《linux/UNIX 系統網絡編程》 Internet domain socket地址有兩種&#xff1a;IPv4 IPv6 IPv4被存儲在結構體中&#xff0c; 該結構體在 netinet/in.h 中進行定義 cd usr/include/netinet/in.h struct in_addr {in_addr_t s_addr; //32位IPv4地址 }struct so…

淺談socket網絡編程函數參數(一)

socket函數解析 概念: 每個進程的進程空間里都有一個socket描述符表。套接字描述符表屬于一個進程&#xff0c;而socket地址結構位于操作系統的內核緩沖。 函數原型 #include <sys/socket.h>int socket(int domain, int type, int protocol);函數參數 family參數 默…

C++ const 與 extern

C語言中&#xff0c; const修飾的全局變量是外部鏈接屬性&#xff0c;比如在 a.c文件中有 const int m_a 10; 在b.c中想用這個全局變量&#xff0c; 在b.c中這樣 extern const int m_a; 就可以使用a.c中的m_a C 語言中&#xff0c; const修飾的全局變量是內部鏈接屬性&#x…

淺談socket網絡編程函數參數(二)

bind()函數 bind()函數把一個地址族中的特定地址賦給socket。 例如對應AF_INET、AF_INET6就是把一個ipv4或ipv6地址和端口號組合賦給socket。 int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);參數解析 sockfd&#xff1a;即socket描述字&#xff0c…