理解Linux的進程,線程,PID,LWP,TID,TGID

来源:https://www.cnblogs.com/wipan/archive/2018/08/16/9488318.html
-Advertisement-
Play Games

在Linux的top和ps命令中,預設看到最多的是pid (process ID),也許你也能看到lwp (thread ID)和tgid (thread group ID for the thread group leader)等等,而在Linux庫函數和系統調用里也許你註意到了pthread i... ...


在Linux的top和ps命令中,預設看到最多的是pid (process ID),也許你也能看到lwp (thread ID)和tgid (thread group ID for the thread group leader)等等,而在Linux庫函數和系統調用里也許你註意到了pthread id和tid等等。還有更多的ID,比如pgrp (process group ID), sid (session ID for the session leader)和 tpgid (tty process group ID for the process group leader)。概念太多可能很暈,但是只要對Linux的進程和線程的基本概念有準確的理解,這些ID的含義都迎刃而解。下麵將介紹進程和線程的核心概念,並以一個示常式序來驗證這些ID之間的關係。

 

Linux的進程和線程

Linux的進程和線程有很多異同點,可以Google下。但只要能清楚地理解一下幾點,則足夠理解Linux中各種ID的含義。

  • 進程是資源分配的基本單位,線程是調度的基本單位
  • 進程是資源的集合,這些資源包括記憶體地址空間,文件描述符等等,一個進程中的多個線程共用這些資源。
  • CPU對任務進行調度時,可調度的基本單位 (dispatchable entity)是線程。如果一個進程中沒有其他線程,可以理解成這個進程中只有一個主線程,這個主進程獨享進程中的所有資源。
  • 進程的個體間是完全獨立的,而線程間是彼此依存,並且共用資源。多進程環境中,任何一個進程的終止,不會影響到其他非子進程。而多線程環境中,父線程終止,全部子線程被迫終止(沒有了資源)。

上述第一點說明是最基礎的,也是最重要的。

 

初步理解各種ID。基本上按照重要程度從高到低,在分割線下方的IDs不太重要。

  • pid: 進程ID。
  • lwp: 線程ID。在用戶態的命令(比如ps)中常用的顯示方式。
  • tid: 線程ID,等於lwp。tid在系統提供的介面函數中更常用,比如syscall(SYS_gettid)和syscall(__NR_gettid)。
  • tgid: 線程組ID,也就是線程組leader的進程ID,等於pid。
  • ------分割線------
  • pgid: 進程組ID,也就是進程組leader的進程ID。
  • pthread id: pthread庫提供的ID,生效範圍不在系統級別,可以忽略。
  • sid: session ID for the session leader。
  • tpgid: tty process group ID for the process group leader。

 從上面的列表看出,各種ID最後都歸結到pid和lwp(tid)上。所以理解各種ID,最終歸結為理解pid和lwp(tid)的聯繫和區別

 

下麵的圖是一張描述父子進程,線程之間關係的圖。

上圖很好地描述了用戶視角(user view)和內核視角(kernel view)看到線程的差別:

  • 從用戶視角出發,在pid 42中產生的tid 44線程,屬於tgid(線程組leader的進程ID) 42。甚至用ps和top的預設參數,你都無法看到tid 44線程。
  • 從內核視角出發,tid 42和tid 44是獨立的調度單元,可以把他們視為"pid 42"和"pid 44"。

需要指出的是,有時候在Linux中進程和線程的區分也是不是十分嚴格的。即使線程和進程混用,pid和tid混用,根據上下文,還是可以清楚地區分對方想要表達的意思。上圖中,從內核視角出發看到了pid 44,是從調度單元的角度出發,但是在top或ps命令中,你是絕對找不到一個pid為44的進程的,只能看到一個lwp(tid)為44的線程。

 

理解pid和lwp(tid)的示常式序

下麵利用一個示常式序來進一步理解pid和lwp(tid),以及利用格式化的ps命令列印出各種ID。下麵的程式在main函數中創建了2個子線程,加上main函數這個主線程,一共有3個線程。在3個線程中分別列印pthread id, pid和lwp(tid),來驗證pid和lwp(tid)的關係。

 1 #include <unistd.h>
 2 #include <sys/syscall.h>
 3 #include <stdio.h>
 4 #include <pthread.h>
 5 
 6 #define gettidv1() syscall(__NR_gettid) // new form
 7 #define gettidv2() syscall(SYS_gettid)  // traditional form
 8 
 9 void *ThreadFunc1()
10 {
11         printf("the pthread_1 id is %ld\n", pthread_self());
12         printf("the thread_1's Pid is %d\n", getpid());
13         printf("The LWPID/tid of thread_1 is: %ld\n", (long int)gettidv1());
14         pause();
15 
16         return 0;
17 }
18 
19 void *ThreadFunc2()
20 {
21         printf("the pthread_2 id is %ld\n", pthread_self());
22         printf("the thread_2's Pid is %d\n", getpid());
23         printf("The LWPID/tid of thread_2 is: %ld\n", (long int)gettidv1());
24         pause();
25 
26         return 0;
27 }
28 
29 int main(int argc, char *argv[])
30 {
31         pid_t tid;
32         pthread_t pthread_id;
33 
34         printf("the master thread's pthread id is %ld\n", pthread_self());
35         printf("the master thread's Pid is %d\n", getpid());
36         printf("The LWPID of master thread is: %ld\n", (long int)gettidv1());
37 
38         // 創建2個線程
39         pthread_create(&pthread_id, NULL, ThreadFunc2, NULL);
40         pthread_create(&pthread_id, NULL, ThreadFunc1, NULL);
41         pause();
42 
43         return 0;
44 }

註意編譯的時候要利用-l指定library參數。

# gcc threadTest.c -o threadTest -l pthread

 

執行程式,結果如下:

# ./threadTest
the master thread's pthread id is 140154481125184
the master thread's Pid is 20992
The LWPID of master thread is: 20992
the pthread_1 id is 140154464352000
the thread_1's Pid is 20992
The LWPID/tid of thread_1 is: 20994
the pthread_2 id is 140154472744704
the thread_2's Pid is 20992
The LWPID/tid of thread_2 is: 20993

上述結果說明pthread id是pthread庫提供的ID,在系統級別沒有意義。pid都是線程組leader的進程ID,即20992。而lwp(tid)則是線程ID,分別是20993和20994。

 

同時利用ps來查看結果,註意ps預設只列印進程級別信息,需要用-L選項來查看線程基本信息。

# ps -eo pid,tid,lwp,tgid,pgrp,sid,tpgid,args -L | awk '{if(NR==1) print $0; if($8~/threadTest/) print $0}'
  PID   TID   LWP  TGID  PGRP   SID TPGID COMMAND
20992 20992 20992 20992 20992 30481 20992 ./threadTest
20992 20993 20993 20992 20992 30481 20992 ./threadTest
20992 20994 20994 20992 20992 30481 20992 ./threadTest

從上述結果中可以看到:

  • PID=TGID: 20992
  • TID=LWP: 20993 or 20994
  • 至於SID,30481是bash shell的進程ID。

 

Linux用戶態命令查看線程

top

預設top顯示的是task數量,即進程。

可以利用敲"H",來切換成線程。如下,可以看到實際上有96個線程。也可以直接利用top -H命令來直接列印線程情況。

 

ps

ps的-L選項可以看到線程,通常能列印出LWP和NLWP相關信息。如下命令即可查看線程信息:

ps -eLf

 

pidstat

pidstat -t [-p pid號] 可以列印出線程之間的關係。

 

htop

要在htop中啟用線程查看,開啟htop,然後按<F2>來進入htop的設置菜單。選擇“設置”欄下麵的“顯示選項”,然後開啟“樹狀視圖”和“顯示自定義線程名”選項。按<F10>退出設置。
註:MAC的F2按fn+F2。

 

參考

Linux進程與線程的區別


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

-Advertisement-
Play Games
更多相關文章
  • 請看題! 題目1: Int64 a = 300000000; Int64 b = 248201000; Int64 c = a - b; 請問 c =? 題目2: int a = 300000000; int b = 248201000; int c = a - b; 請問 c =? 請各位大牛們踴 ...
  • 原文轉載http://man.linuxde.net/ftp ftp命令用來設置文件系統相關功能。ftp伺服器在網上較為常見,Linux ftp命令的功能是用命令的方式來控制在本地機和遠程機之間傳送文件,這裡詳細介紹Linux ftp命令的一些經常使用的命令,相信掌握了這些使用Linux進行ftp操... ...
  • COPY 命令: // 描述: 將一個或多個文件從一個位置複製到另一個位置。 ### 註意:如果想複製文件夾,請使用 XCOPY 。 // 語法: copy [/a] [/b] [/d] [/v] [/n] [/z] [/y | /-y] <source> [/a] [/b] [<source> [ ...
  • 返回 "LVS系列文章:http://www.cnblogs.com/f ck need u/p/7576137.html"   加權調度演算法是一種很常見的調度演算法。如果只有兩個後端,調度的順序很容易,但是如果後端多於2個,可能就不像想象中那樣的順序進行調度。 所以,本文揭秘加權調度演算法到 ...
  • 今天是開通博客第一天, 第一次寫博客,也不知道寫什麼, 以後寫點技術文,把我的經驗分享給大家, 不對的地方請大家指正,一起進步。我要把我每遇到的難題以及學到的知識和技術為大家踩坑, 做研究。同時有時候寫一點自己的感想,對一些事物的看法等。自己文筆不好,見諒了。謝謝大家。 ...
  • 本文將介紹如何在Linux上部署Django + Mysql + Apache環境。我們知道,Django內置的http伺服器只能工作在單線程下,做開發和調試時候是可以的,但是生產環境通常都會有多用戶併發,而且django的simple HTTP server處理大量靜態文件的性能太差,所以要用ap ...
  • NFS網路文件系統 如果大家覺得Samba服務程式的配置太麻煩了,那麼你共用文件的主機都是Linux系統,那麼推薦大家在客戶端部署nfs服務來共用文件.nfs(網路文件系統)服務可以將遠程Linux系統上的文件共用資源掛載到本地主機的目錄上,從而使得本地主機客戶端基於TCP/IP協議,像是用本地主機 ...
  • 不論是學習還是工作,我們都會跟各種類型的文檔打交道,時間久了,遇到的問題也會千奇百怪,比如:將PDF轉換成圖片的問題你遇到過嗎?這個時候別慌,多學習一些技能,就能游刃有餘。小編這裡就有一個現成的PDF轉換成圖片的教程, 大家可以學習一下,以備不時之需。 1、前往線上PDF轉換平臺——pdf365.c ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...