如何正確編寫linux守護進程

1、守護進程,也就是通常說的Daemon進程,是Linux中的后臺服務進程。它是一個生存期較長的進程,通常獨立于控制終端并且周期性地執行某種任務或等待處理某些發生的事件。如果想讓某個進程不因為用戶或終端或其他地變化而受到影響,那么就必須把這個進程變成一個守護進程。

2、創建守護進程步驟

1)創建子進程,父進程退出

??? 之后的所有工作都在子進程中完成,而用戶在Shell終端里則可以執行其他命令,從而在形式上做到了與控制終端的脫離。

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

2)在子進程中創建新會話

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

??? 會話周期:會話期是一個或多個進程組的集合。通常,一個會話開始于用戶登錄,終止于用戶退出,在此期間該用戶運行的所有進程都屬于這個會話期。

1pid_t setsid(void);

??? setsid() creates a new session if the calling process is not a process group leader. The calling process will be the only process in this new process group and in this new session.

??? setsid函數用于創建一個新的會話,并擔任該會話組的組長。調用setsid有下面的3個作用:

① 讓進程擺脫原會話的控制

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

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

有以下三個結果:

a)成為新會話的首進程

b)成為一個新進程組的組長進程

c)沒有控制終端。

有些人建議在此時再次調用fork,并使父進程終止。第二個子進程作為守護進程繼續運行。這樣就保證了該守護進程不是會話首進程。

??? setsid函數能夠使進程完全獨立出來,從而擺脫其他進程的控制。

??? setsid()調用成功后,進程成為新的會話組長和新的進程組長,并與原來的登錄會話和進程組脫離。由于會話過程對控制終端的獨占性,進程同時與控制終端脫離。 子進程可以自己組成一個新的進程組,即調用setpgrp()與原進程組脫離關系,產生一個新的進程組,進程組號與它的進程號相同.這樣,父進程退出運行后就不會影響子進程的當前運行.

3改變當前目錄為根目錄

??? 使用fork創建的子進程繼承了父進程的當前工作目錄;進程活動時,其工作目錄所在的文件系統不能卸下。通常的做法是讓"/"作為守護進程的當前工作目錄,也可以是其他目錄,如/tmp,使用chdir

4)重設文件權限掩碼

文件權限掩碼是指屏蔽掉文件權限中的對應位。比如,有個文件權限掩碼是050,它就屏蔽了文件組擁有者的可讀與可執行權限。mask = mask & ~050

通常,把文件權限掩碼設置為0umask(0)

5)關閉文件描述符

fork函數新建的子進程會從父進程那里繼承已經打開了的文件描述符。這些被打開的文件可能永遠不會被守護進程讀寫,但它們一樣消耗系統資源,而且可能導致所在的文件系統無法卸下。

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

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

??? close(i);

6守護進程退出處理

當用戶需要外部停止守護進程運行時,往往會使用 kill命令停止該守護進程。所以,守護進程中需要編碼來實現kill發出的signal信號處理,達到進程的正常退出。

signal(SIGTERM, sigterm_handler);

void sigterm_handler(int arg)

{

_running = 0;

}

7)處理SIGCHLD信號

??? 處理SIGCHLD信號并不是必須的。但對于某些進程,特別是服務器進程往往在請求到來時生成子進程處理請求。如果父進程不等待子進程結束,子進程將成為僵尸進程(zombie)從而占用系統資源。如果父進程等待子進程結束,將增加父進程的負擔,影響服務器進程的并發性能。在Linux下可以簡單地將 SIGCHLD信號的操作設為SIG_IGN

??? signal(SIGCHLD,SIG_IGN);

??? 這樣,內核在子進程結束時不會產生僵尸進程。

?

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

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

相關文章

Linux(6)-命令行的使用,history,shell腳本

命令行的使用,shell腳本1.終端shell,man1.1 Ctrlr--匹配查找歷史命令1.2 history [n] --列出歷史命令1.3&#xff01;--執行歷史命令2.shell 編程2.1 shell腳本2.2 注釋2.3 指明所用的shell2.4 支持函數2.5 使用變量2.6 解析命令行參數2.7 if, for, case, while2.8 shell腳本中…

lua元表的理解

元表概念 &#xff08; Metatable&#xff09;元表由鍵名為 事件 (event) 和其中的值叫作元方法 (metamethod)組成。在lua中每個值都有一個元表。而table和userdata所定義的值允許自定義對應的元表&#xff0c;其他都是用統一的元表。我的理解&#xff0c;元表&#xff0c;其實…

程序以及論文

本人長期承接大學計算機專業的畢業設計和論文的編寫。 主要開發語言C&#xff0c;C &#xff08;windows或linux平臺皆可&#xff09;&#xff0c;php&#xff0c;c#&#xff0c;VC 。 課題內容可以是 管理系統&#xff0c;可以是 網站設計開發 可以是 網絡聊天 可以是 應用…

Github(1)-概覽,初始化倉庫

Github網頁-本地git1.github網頁1.1 主要界面1.1.1github主頁1.1.2倉庫主頁1.1.3 個人頁面1.2 注冊github賬號1.3 新建平臺倉庫2.git-本地倉庫2.1 git本地倉庫的三個區域2.2 創建一個本地倉庫GitHub 本質上是一個代碼托管平臺&#xff0c;它提供的是基于 Git 的代碼托管服務。G…

Lua 協程

Lua里的協程是一個原來沒見過的東西&#xff0c;Python的Gevent也是一個基于coroutine的python網絡開發框架。性能據說很不錯。協同的一個關鍵特征是它可以不斷顛倒調用者與被調用者之間的關系協程和一般多線程的區別是&#xff0c;一般多線程由系統決定該哪個線程執行&#xf…

leetcode16 最接近的三數之和

給定一個包括 n 個整數的數組 nums 和 一個目標值 target。找出 nums 中的三個整數&#xff0c;使得它們的和與 target 最接近。返回這三個數的和。假定每組輸入只存在唯一答案。 例如&#xff0c;給定數組 nums [-1&#xff0c;2&#xff0c;1&#xff0c;-4], 和 target 1…

LINUX下動態鏈接庫的使用-dlopen dlsym dlclose dlerror

dlopen 基本定義   功能&#xff1a;打開一個動態鏈接庫 包含頭文件&#xff1a; #include <dlfcn.h> 函數定義&#xff1a; void * dlopen( const char * pathname, int mode ); 函數描述&#xff1a; 在dlopen的&#xff08;&#xff09;函數以指定模式打開指定的動…

leecode11 盛水最多的容器

給定 n 個非負整數 a1&#xff0c;a2&#xff0c;...&#xff0c;an&#xff0c;每個數代表坐標中的一個點 (i, ai) 。在坐標內畫 n 條垂直線&#xff0c;垂直線 i 的兩個端點分別為 (i, ai) 和 (i, 0)。找出其中的兩條線&#xff0c;使得它們與 x 軸共同構成的容器可以容納最多…

Github(2)-本地配置git

本地配置git1.注冊賬號2.安裝git工具3.配置git 賬號1.注冊賬號 github網頁注冊github賬戶 2.安裝git工具 本地安裝git工具 step1 查看是否安裝git git version step2 mac 安裝 brew install git step2 linux安裝 sudo apt-get install git 3.配置git 賬號 創建ssh key, 配置…

lua面向對象編程之點號與冒號的差異詳細比較

首先,先來一段在lua創建一個類與對象的代碼 Class {}Class.__index Classfunction Class:new(x,y)local temp {}setmetatable(temp, Class)temp.x xtemp.y yreturn tempendfunction Class:test()print(self.x,self.y)endobject Class.new(10,20)object:test() 猜一下會輸…

lua __index __newindex upvalue 示例

項目中有個公會對象&#xff0c;數據大部分存在data中&#xff0c;之前都是 u.data.point這樣訪問&#xff0c;太麻煩了。 于是通過設置__index 使之可以直接訪問屬性&#xff0c;u.point。 但是還是不能直接改屬性&#xff0c;u.point 4&#xff0c;所以再設置了__newindex…

leecode26 刪除排序數組中的重復項

給定一個排序數組&#xff0c;你需要在原地刪除重復出現的元素&#xff0c;使得每個元素只出現一次&#xff0c;返回移除后數組的新長度。 不要使用額外的數組空間&#xff0c;你必須在原地修改輸入數組并在使用 O(1) 額外空間的條件下完成。 示例 1: 給定數組 nums [1,1,2…

MachineLearning(6)-Daviad Silver強化學習課程脈絡整理

強化學習-Daviad Silver強化學習課程脈絡整理1.lecture1 introduction1.1 強化學習簡介1.2 強化學習類別1.3 強化學習的主要問題2.lecture2 Markov Decision Process2.1 MP,MRP,MDP2.2 Bellman Eqution--貝爾曼方程2.3 Bellman Eqution--貝爾曼期望方程2.4 最優策略2.5 最優值函…

lua的VS或者VC環境的搭建調試

安裝完LuaForWindows_v5.1.4 打開vs tools->options->projects->directories executable files 選項添加lua安裝以后的路徑,我的是 C:\Program Files\Lua\5.1 include files選項添加lua include路徑,我的是 C:\Program Files\Lua\5.1include library files 選項添…

leecode53 最大子序列和

給定一個整數數組 nums &#xff0c;找到一個具有最大和的連續子數組&#xff08;子數組最少包含一個元素&#xff09;&#xff0c;返回其最大和。 示例: 輸入: [-2,1,-3,4,-1,2,1,-5,4], 輸出: 6 解釋: 連續子數組 [4,-1,2,1] 的和最大&#xff0c;為 6。 思路&#xff1a;…

在頁游中LUA的應用(1)

通常,你希望在你的游戲開始的時候讀取一些信息,以配置你的游戲,這些信息通常都是放到一個文本文件中,在你的游戲啟動的時候,你需要打開這個文件,然后解析字符串,找到所需要的信息。 或許你認為這樣就足夠了,為什么還要使用Lua呢? 應用于“配置”這個目的,Lua提供給你…

Github(3)-本地文件管理

使用github 托管代碼簡單使用教程--本地文件管理1.基本概念2.本地文件管理2.1 git add2.2 git status2.3 git commit2.3 git log2.5 git reset --hard 版本回退2.6 git reflog2.7 git diff2.8 git checkout --file 工作區文件恢復2.9 git rm 刪除版本庫里的文件廖雪峰老師博文學…

linux 中阻塞與非阻塞 同步與異步

簡單點說: 阻塞就是干不完不準回來&#xff0c; 非阻塞就是你先干&#xff0c;我先看看有其他事沒有&#xff0c;完了告訴我一聲。 我們拿最常用的send和recv兩個函數來說吧。比如你調用send函數發送一定的Byte,在系統內部send做的工作其實只是把數據傳輸(Copy)到TCP/IP協議棧…

leecode62 不同路徑

示例 1: 輸入: m 3, n 2 輸出: 3 解釋: 從左上角開始&#xff0c;總共有 3 條路徑可以到達右下角。 1. 向右 -> 向右 -> 向下 2. 向右 -> 向下 -> 向右 3. 向下 -> 向右 -> 向右 示例 2: 輸入: m 7, n 3 輸出: 28 思路&#xff1a;太過于簡單&#xf…

數據庫的查詢優化建議整理

從大多數數據庫應用系統的實例來看,查詢操作在各種數據庫操作中所占據的比重最大,而查詢操作所基于的SELECT語句在SQL語句中又是代價最大的語句。 查詢語句(SELECT)的優化建議 (1)、合理使用索引:where子句中變量順序應與索引字鍵順序相同。 如:create index test_idx…