進程與線程的關系和區別


         進程與線程的關系和區別

一、定義

進程:具有一定獨立功能的程序關於某個數據集合上的一次運行活動,進程是系統進行資源分配和調度的一個獨立單位。

線程:是進程的一個實體,是cpu調度和分派的基本單位,它是比進程更小的能獨立運行的基本單位。線程自己基本上不擁有系統資源,只擁有一點在運行中必不可少的資源,但是它可以和同屬於一個進程的其他線程共享進程所擁有的的全部資源。

二、關系和區別

一個線程可以創建和撤銷另一個線程;同一個進程中的多個線程之間可以並發執行。相對於進程而言,線程是一個更加接近於執行體的概念,它可以與同進程中的其他進程共享數據,但是擁有自己的棧空間,擁有獨立的運行序列。

區別主要有以下幾點:

調度:進程是擁有資源的基本單位,線程是調度和分派的基本單位。
共享地址空間:進程擁有各自獨立的地址空間、資源,所以共享復雜,需要用IPC(Inter-Process Communication,進程間通信),但是同步簡單。而線程共享所屬進程的資源,因此共享簡單,但是同步復雜,需要用加鎖等措施。
占用內存和cpu:進程占用內存多,切換復雜,cpu利用率低;而線程占用內存少,切換簡單,cpu利用率高。
互相影響:進程之間不會互相影響;而一個線程掛掉會導致整個進程掛掉。
三、關於僵屍進程

產生原因:當子進程比父進程先運行結束,而父進程沒有回收子進程時,子進程將會成為一個僵屍進程。如果父進程先退出了,那么子進程將會被init接管,從而就不會成為僵屍進程了。

如何避免僵屍進程的產生?

解決方法有以下幾種:

父進程通過wait或waitpid等待子進程結束,但是這會導致父進程掛起。
如果父進程很忙,那么可以用signal函數為SIGCHLD安裝handler,這樣在子進程結束后,父進程會收到該信號,就可以在handler中調用wait回收。
若父進程不關心子進程何時結束,那么可以用 signal(SIGCHLD, SIG_IGN) 通知內核自己對於子進程的結束不感興趣,這樣子進程結束后內核會回收,並不會再給父進程發送信號。
讓僵屍進程變為“孤兒進程”(即殺死其父進程),過繼給1號進程init,init始終會負責清理僵屍進程。
linux下如何查看和殺死僵屍進程?

使用 top 命令可以查看當前是否存在僵屍進程,運行結果如下圖:

 

可以看到當前系統中有6個僵屍進程,確定存在僵屍進程了,那么如何定位呢?別急,請往下看 ↓

定位僵屍進程和其父進程:ps -A -o stat,ppid,pid,cmd | grep -e '^[Zz]'

【注】:-A表示列出所有進程;-o 是自定義輸出字段,我們設定顯示字段為 stat(狀態), ppid(進程父id), pid(進程id),cmd(命令)這四個參數;由於狀態為 z或者Z的進程為僵屍進程,所以我們使用grep抓取stat狀態為zZ進程。

運行結果如下圖:

一、定義

進程:具有一定獨立功能的程序關於某個數據集合上的一次運行活動,進程是系統進行資源分配和調度的一個獨立單位。

線程:是進程的一個實體,是cpu調度和分派的基本單位,它是比進程更小的能獨立運行的基本單位。線程自己基本上不擁有系統資源,只擁有一點在運行中必不可少的資源,但是它可以和同屬於一個進程的其他線程共享進程所擁有的的全部資源。

二、關系和區別

一個線程可以創建和撤銷另一個線程;同一個進程中的多個線程之間可以並發執行。相對於進程而言,線程是一個更加接近於執行體的概念,它可以與同進程中的其他進程共享數據,但是擁有自己的棧空間,擁有獨立的運行序列。

區別主要有以下幾點:

調度:進程是擁有資源的基本單位,線程是調度和分派的基本單位。
共享地址空間:進程擁有各自獨立的地址空間、資源,所以共享復雜,需要用IPC(Inter-Process Communication,進程間通信),但是同步簡單。而線程共享所屬進程的資源,因此共享簡單,但是同步復雜,需要用加鎖等措施。
占用內存和cpu:進程占用內存多,切換復雜,cpu利用率低;而線程占用內存少,切換簡單,cpu利用率高。
互相影響:進程之間不會互相影響;而一個線程掛掉會導致整個進程掛掉。
三、關於僵屍進程

產生原因:當子進程比父進程先運行結束,而父進程沒有回收子進程時,子進程將會成為一個僵屍進程。如果父進程先退出了,那么子進程將會被init接管,從而就不會成為僵屍進程了。

如何避免僵屍進程的產生?

解決方法有以下幾種:

父進程通過wait或waitpid等待子進程結束,但是這會導致父進程掛起。
如果父進程很忙,那么可以用signal函數為SIGCHLD安裝handler,這樣在子進程結束后,父進程會收到該信號,就可以在handler中調用wait回收。
若父進程不關心子進程何時結束,那么可以用 signal(SIGCHLD, SIG_IGN) 通知內核自己對於子進程的結束不感興趣,這樣子進程結束后內核會回收,並不會再給父進程發送信號。
讓僵屍進程變為“孤兒進程”(即殺死其父進程),過繼給1號進程init,init始終會負責清理僵屍進程。
linux下如何查看和殺死僵屍進程?

使用 top 命令可以查看當前是否存在僵屍進程,運行結果如下圖:

 

 

 

可以看到當前系統中有6個僵屍進程,確定存在僵屍進程了,那么如何定位呢?別急,請往下看 ↓

定位僵屍進程和其父進程:ps -A -o stat,ppid,pid,cmd | grep -e '^[Zz]'

【注】:-A表示列出所有進程;-o 是自定義輸出字段,我們設定顯示字段為 stat(狀態), ppid(進程父id), pid(進程id),cmd(命令)這四個參數;由於狀態為 z或者Z的進程為僵屍進程,所以我們使用grep抓取stat狀態為zZ進程。

運行結果如下圖:

 

 

 

可以看到存在的6個僵屍進程的ID及其父進程的ID。

獲得僵屍進程的父進程ID之后,我們就可以使用命令殺死它了。

kill -9 父進程ID

例如:kill -9 16092

如果僵屍進程多了,這樣一個一個處理豈不是很慢?別着急,來個批處理命令一次搞定:

ps -A -o stat,ppid,pid,cmd | grep -e '^[Zz]' | awk '{print $2}' | xargs kill -9

【注】:管道是 Linux 使用的主要進程間通信機制之一。一般而言,管道采用異步發送,阻塞式接收 (blocking receive) 操作,即接收進程在管道沒有有效數據時被掛起等待。在 Shell中使用管道符 “|” 可以將一個命令的輸出重定向到另一個命令的輸入,可以嵌套運行,管道連接的每個命令程序都按一個獨立進程執行, 整串命令的退出狀態是最后一個命令的退出狀態。

awk '{print $2}'作用是 一行一行地讀取前面的查找結果,打印第二個字段(即ppid);

xargs kill -9 中的 xargs 命令是用來把前面命令的輸出結果作為"kill -9"命令的參數,並執行該命令。
————————————————


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM