linux進程管理總結

来源:https://www.cnblogs.com/chenfangzhi/archive/2019/04/05/10660355.html
-Advertisement-
Play Games

[TOC] 一、進程相關的概念 進程需要瞭解 進程,父進程,進程組,會話和控制終端的相關概念。 1. 進程和父進程:每個進程都有父進程,而所有的進程以init進程為根,形成一個樹狀結構 2. 進程組:每個進程都會屬於一個進程組(process group),每個進程組中可以包含多個進程。進程組會有一 ...


目錄

一、進程相關的概念

進程需要瞭解 進程,父進程,進程組,會話和控制終端的相關概念。

  1. 進程和父進程:每個進程都有父進程,而所有的進程以init進程為根,形成一個樹狀結構

  2. 進程組:每個進程都會屬於一個進程組(process group),每個進程組中可以包含多個進程。進程組會有一個進程組領導進程 (process group leader),領導進程的PID成為進程組的ID (process group ID, PGID),以識別進程組。

    kill給組發送信號進程組號前加負號如:kill -9 -2189

  3. 會話:一個或是多個進程組集合。 進程可以通過調用 pid_t setsid(); 來建立一個新會話,如果調用此函數的進程不是進程組長,就會創建一個新的會話,那麼此時會:
    1. 該進程稱為會話首進程 (session leader)
    2. 該進程稱為進程組組長
    3. 該進程沒有控制終端,即使之前有控制終端這種聯繫也會斷掉

      可以使用第三個特性來創建 daemon 進程。 調用 getsid 可以獲得會話首進程進程組 pid,也就是會話首進程進程 id。

  4. 控制終端:
    1. 一個會話持有一個控制終端 (controlling terminal),可以是終端設備也可以是偽終端
    2. 建立與控制終端連接的會話首進程被稱為控制進程 (controlling process)
    3. 一個會話有多個進程組,允許存在多個後臺進程組 (backgroup process group) 和一個前臺進程組 (foregroup process group)
    4. 鍵入終端的中斷鍵 (Ctrl+C) 會發送中斷信號給前臺進程組所有進程
    5. 鍵入終端的退出鍵 (Ctrl+) 會發送退出信號給前臺進程組所有進程
    6. 終端或是網路斷開會將掛斷信號發送給會話首進程

可以看到執行ps -fj結果如下:


UID         PID   PPID   PGID    SID  C STIME TTY          TIME CMD
chen      36829  36825  36829  36829  0 10:56 pts/0    00:00:00 -bash
chen      37247  36829  37247  36829  0 10:57 pts/0    00:00:00 vim
chen      90490  36829  90490  36829  0 11:57 pts/0    00:00:00 ps -fj

其中PID就是進程id,PPID是父進程id,PGID為進程組id,SID為會話ID

二、關閉會話時子進程進程被殺死

終端在關閉時會發送SIGHUP信號給session leader,此處就是bash進程,bash收到後向session內的所有進程發送SIGHUP然後退出。
SIGHUP信號如果為註冊處理函數預設行為就是退出。所以會話退出時子進程都被殺死。

解決方案:

  1. 註冊SIGHUP信號處理函數:可以在代碼中處理或者使用nohup命令(nohup daemon & &>daemon.log)
  2. 重新設置setsid:可以在代碼中處理或者使用setsid命令(setsid daemon)

三、nohup的原理

其實很簡單就是註冊了SIGHUP的一個處理函數,忽略這個信號,然後去執行實際的命令。
源碼地址:https://github.com/MaiZure/coreutils-8.3/blob/master/src/nohup.c,nohup的使用也推薦< /dev/null來重定向stdin

關鍵代碼:

   // 註冊處理函數
  signal (SIGHUP, SIG_IGN);

  char **cmd = argv + optind;
  //執行實際的代碼
  execvp (*cmd, cmd);

四、setsid原理

fork進程之後的子進程共用父進程的很多東西,並且會話組長就是父進程的會長組長,所以會收到來自父進程會話組長的信號。
setsid用餘新建一個會話,調用這個函數之後會噹噹前進程成為進程組組長和會話組組長,那麼原來的會話產生的信號便不會發送到這個進程,從而不會受影響。

五、daemon &和守護進程的區別

因為守護進程的實現是用的setsid,所以其實就是setsid和nohup的區別,兩者都可以用來防止進程在終端斷開的時候被殺死,nohup還需要配合&放入後臺運行。區別的的話守護進程已經脫離了終端,不受終端控制,也就沒有 了stdin,stdout和stderr,而使用nohup之後的進程還是有一個終端,只是忽略了其中的SIGHUP信號,存在正常的stdin,stdout和stderr,nohup預設將stdout和stderr重定向到了nohup.out。

最佳實踐:

  1. 如果是一次性的後臺任務,可以使用nohup十分方便
  2. 如果是長期運行的服務,則推薦使用系統的systemd來管理服務
  3. 如果是定時運行的任務則推薦使用cron來運行

六、服務進程為什麼要fork兩次

首先說明兩次不是必須的,有很多程式都採用了一次fork。

第一次:為了調用setsid,這也解釋了為什麼調用setsid之前需要先fork的原因:
linux規定調用這個函數之前,當前進程不允許是session leader。進程組leader是該進程組的第一個進程,fork出來的進程必定不是第一個,所以可以調用setsid。另外父進程一般直接退出,可以讓shell收到進程結束的通知繼續執行,而不是等待他結束。

第二次:為了限制進程打開控制終端,只有會話組長能打開控制終端(非必須,相當於加了個限制條件Daemon不需要打開終端)

七、systemd管理daemon

現在很多的linux發行版都採用systemd來代替原來的init程式,systemd提供了很優秀的進程管理功能,我們需要註冊服務時可以利用systemd功能,可以參看鳥哥的systemd介紹。

另外補充點內核進程和Systemd進程:
0號進程為內核進程,1號為Systemd進程,其他還有些內核進程在ps命令查看時以[]包裹。具體關係見:LINUX PID 1 和 SYSTEMD

八、僵屍進程

這個定義摘抄自維基百科:在類UNIX系統中,僵屍進程是指完成執行(通過exit系統調用,或運行時發生致命錯誤或收到終止信號所致)但在操作系統的進程表中仍然有一個表項(進程式控制制塊PCB),處於"終止狀態"的進程。這發生於子進程需要保留表項以允許其父進程讀取子進程的exit status:一旦退出態通過wait系統調用讀取,僵屍進程條目就從進程表中刪除,稱之為"回收(reaped)"。

九、進程名字和啟動時指定進程名字

kill,ps,top,pstree這些命令都比較熟悉就不再提了。

至於還有一組命令則不是通過進程號而是通過進程名字來操作進程,pkill和killall一樣都是通過名字來殺死進程,而pgrep是通過名字來尋找進程。
他們的原理都是通過查找/proc這個記憶體文件系統。

在啟動的時候可以通過exec命令重命名:
bash -c "exec -a myname sleep 500 &"

你可以通過ps -ef|grep myname來查看進程的詳細信息

十、source command和./command 和exec命令的區別

通常執行腳本有三種方式

  1. ./command(同sh command)
  2. source command(同. command)
  3. exec command

簡單說明下上面三種方式:

第一種其實就是對應了linux的fork系統調用,在執行command時候,command是在子進程中執行的,當前shell等待直到子進程的command運行完畢在返回到當前shell。第二種則是直接在當前的進程中直接執行,執行完繼續接受用戶輸入。第三種則對應了linux的exec系統調用,當前進程的執行流程會轉向command,command是在當前進程直接執行,但是執行完之後便會直接退出。

所以我們一般用的是第一和第二兩種,這種的主要區別就是開不開新的進程(開進程是要一定開銷的),另外因為第二種是在當前進程執行的,所以如果在command中設置了變數,那麼相當於在當前進程中設置了變數,所以我們一般是用第一種去執行避免當前進程的變數被污染。

思考:

現在加入你在終端已經運行了一個非常耗時的任務,你按ctrl+z放入了後臺,然後利用bg開始任務,因為終端斷開就會收到SIGHUP信號,有沒有辦法忽略這個信號或者終端斷開不收到這個信號?

遺留:

進程調試工具:ltrace strace ftrace

參考鏈接:

  1. Linux進程組和會話
  2. 線上APUE譯文
  3. linux終端關閉時為什麼會導致在其上啟動的進程退出?
  4. What's the difference between nohup and a daemon?

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 繼上一篇,介紹 CYQ.Data 在分散式緩存上支持高可用,詳見:CYQ.Data 對於分散式緩存Redis、MemCache高可用的改進及性能測試,本篇介紹 CYQ.Data 在對資料庫層面對分散式資料庫的主從備的高可用的及負載調度。 ...
  • .mmmm 課堂總結 .mmmm 課堂總結 通過本次的課堂學習,我瞭解了很多關於python的基礎知識。同時,相比較於之前學過的編程語言(例:java ,c/c++…)有很多相同之處,也有很多不同之處。相比較於Java,c/c++ 語言,python在語法上是比較簡單的,例如一條簡單的輸出語句,在j ...
  • 依賴屬性 暫無 附加屬性 1.在沒有控制項源碼的前提下增加控制項的屬性 2.多個控制項需要用到同一種屬性 使用附加屬性可以減少代碼量,不必為每一個控制項都增加依賴屬性 3.屬性不確定是否需要使用 在某些上下文中需要就被附加上去。比如TextBox的Grid.Row屬性,如果我們定義TextBox類時定義一個 ...
  • 原文鏈接:http://www.entityframeworktutorial.net/code-first/column-dataannotations-attribute-in-code-first.aspx Column特性,可以應用於實體的一個或者多個屬性上面,用來配置資料庫中數據表中列的列 ...
  • 原文地址:http://www.entityframeworktutorial.net/code-first/table-dataannotations-attribute-in-code-first.aspx Table特性可以應用於一個領域類上面,用來在資料庫中生成相應名稱的數據表。它重寫了EF ...
  • System.Objec時C#中所有類型的基類,也就是萬類之源。 一、值類型 值類型都繼承自System.ValueType(派生自System.Objec),繼承自System.ValueType的類型在CLR中具有特殊的行為,值類型變數直接包含它們的值。對於值類型變數,沒有單獨的堆分配或垃圾回收 ...
  • 日常編程中經常用到++i與i++,知識點雖然很小,但有時候會犯迷糊,在這裡小小的記錄一下。 ++i 即前遞增,顧名思義也就是先自增後傳值; 舉個慄子 此時i的值為6,j的值也為6。 i++即後遞增,顧名思義也就是先傳值後自增 舉個慄子 此時i的值為6,j的值為5。 ...
  • 一丶前言 看過一些描述關於AOP切麵編程的文章,寫的太概念化讓人很難理解,下麵是我自己的理解,希望能幫到新人,如有錯誤歡迎指正。 二丶AOP是什麼,它的應用場景是什麼? AOP也跟IOC,OOP這些思想一樣它只是一種編程思想。Autofac、Spring.Net、Castle這些組件實現了AOP切麵 ...
一周排行
    -Advertisement-
    Play Games
  • 前言 本文介紹一款使用 C# 與 WPF 開發的音頻播放器,其界面簡潔大方,操作體驗流暢。該播放器支持多種音頻格式(如 MP4、WMA、OGG、FLAC 等),並具備標記、實時歌詞顯示等功能。 另外,還支持換膚及多語言(中英文)切換。核心音頻處理採用 FFmpeg 組件,獲得了廣泛認可,目前 Git ...
  • OAuth2.0授權驗證-gitee授權碼模式 本文主要介紹如何筆者自己是如何使用gitee提供的OAuth2.0協議完成授權驗證並登錄到自己的系統,完整模式如圖 1、創建應用 打開gitee個人中心->第三方應用->創建應用 創建應用後在我的應用界面,查看已創建應用的Client ID和Clien ...
  • 解決了這個問題:《winForm下,fastReport.net 從.net framework 升級到.net5遇到的錯誤“Operation is not supported on this platform.”》 本文內容轉載自:https://www.fcnsoft.com/Home/Sho ...
  • 國內文章 WPF 從裸 Win 32 的 WM_Pointer 消息獲取觸摸點繪製筆跡 https://www.cnblogs.com/lindexi/p/18390983 本文將告訴大家如何在 WPF 裡面,接收裸 Win 32 的 WM_Pointer 消息,從消息裡面獲取觸摸點信息,使用觸摸點 ...
  • 前言 給大家推薦一個專為新零售快消行業打造了一套高效的進銷存管理系統。 系統不僅具備強大的庫存管理功能,還集成了高性能的輕量級 POS 解決方案,確保頁面載入速度極快,提供良好的用戶體驗。 項目介紹 Dorisoy.POS 是一款基於 .NET 7 和 Angular 4 開發的新零售快消進銷存管理 ...
  • ABP CLI常用的代碼分享 一、確保環境配置正確 安裝.NET CLI: ABP CLI是基於.NET Core或.NET 5/6/7等更高版本構建的,因此首先需要在你的開發環境中安裝.NET CLI。這可以通過訪問Microsoft官網下載並安裝相應版本的.NET SDK來實現。 安裝ABP ...
  • 問題 問題是這樣的:第三方的webapi,需要先調用登陸介面獲取Cookie,訪問其它介面時攜帶Cookie信息。 但使用HttpClient類調用登陸介面,返回的Headers中沒有找到Cookie信息。 分析 首先,使用Postman測試該登陸介面,正常返回Cookie信息,說明是HttpCli ...
  • 國內文章 關於.NET在中國為什麼工資低的分析 https://www.cnblogs.com/thinkingmore/p/18406244 .NET在中國開發者的薪資偏低,主要因市場需求、技術棧選擇和企業文化等因素所致。歷史上,.NET曾因微軟的閉源策略發展受限,儘管後來推出了跨平臺的.NET ...
  • 在WPF開發應用中,動畫不僅可以引起用戶的註意與興趣,而且還使軟體更加便於使用。前面幾篇文章講解了畫筆(Brush),形狀(Shape),幾何圖形(Geometry),變換(Transform)等相關內容,今天繼續講解動畫相關內容和知識點,僅供學習分享使用,如有不足之處,還請指正。 ...
  • 什麼是委托? 委托可以說是把一個方法代入另一個方法執行,相當於指向函數的指針;事件就相當於保存委托的數組; 1.實例化委托的方式: 方式1:通過new創建實例: public delegate void ShowDelegate(); 或者 public delegate string ShowDe ...