国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統(tǒng) > Linux > 正文

[轉(zhuǎn)載]了解Linux的進程與線程

2024-06-28 13:22:26
字體:
供稿:網(wǎng)友
[轉(zhuǎn)載]了解linux的進程與線程 2015-01-19 15:57 by 瀟湘隱者, ... 閱讀, ... 評論, 收藏, 編輯

本文轉(zhuǎn)自Tim Yang的博客http://timyang.net/linux/linux-PRocess/ 。對于理解Linux的進程與線程非常有幫助。支持原創(chuàng)、尊重原創(chuàng),分享知識!

上周碰到部署在真實服務(wù)器上某個應(yīng)用CPU占用過高的問題,雖然經(jīng)過tuning, 問題貌似已經(jīng)解決,但我對tuning的方式只是基于大膽的假設(shè)并最終生效了。我更希望更多的求證一下程序背后CPU及OS kernel當(dāng)時的運作機制。所以我讀了一些Linux內(nèi)核設(shè)計與實現(xiàn)及其他一些相關(guān)資料,對Linux process的機制與切換有了更多一些體會。本文盡可能條理一點,但由于牽涉點較多,同時自己可能覺得某些點有記錄的價值,因此文字可能會零散。

進程狀態(tài)

Linux進程的狀態(tài)比較容易理解,值得注意的是 UNINTERRUPTIBLE 及 ZOMBIE

TASK_RUNNINGTASK_INTERRUPTIBLETASK_UNINTERRUPTIBLE 此時進程不接收信號,這就是為什么有時候kill一個繁忙的進程沒有響應(yīng)。TASK_ZOMBIE 我們經(jīng)常 kill -9 pid 之后運行ps會發(fā)現(xiàn)被kill的進程仍然存在,狀態(tài)為 zombie。zombie的進程實際上已經(jīng)結(jié)束,占用的資源也已經(jīng)釋放,僅由于kernel的相關(guān)進程描述符還未釋放。TASK_STOPPED

Kernel Space and User Space

Kernel Space是供內(nèi)核,設(shè)備驅(qū)動運行的內(nèi)存區(qū)域。User space是供普通應(yīng)用程序運行的區(qū)域。每一個進程都運行在自己的虛擬內(nèi)存區(qū)域,不能訪問其他進程的內(nèi)存空間。普通進程不能訪問Kernel Space, 只能通過系統(tǒng)調(diào)用來間接進行。當(dāng)系統(tǒng)內(nèi)存比較緊張時,非當(dāng)前運行進程User Space可能會被swap到磁盤。

使用命令 pmap -x <pid> 可以查看進程的內(nèi)存占用信息; lsof -a -p <pid> 可以查看一個進程打開的文件信息。ps -Lf <pid> 可以查看進程的線程數(shù)。

另外procfs也是一個分析進程結(jié)構(gòu)的好地方。procfs是一個虛擬的文件系統(tǒng),它把系統(tǒng)中正在運行的進程都顯現(xiàn)在/proc/<pid>目錄下。

進程創(chuàng)建

  

  進程創(chuàng)建通常調(diào)用fork實現(xiàn)。創(chuàng)建后子進程和父進程指向同一內(nèi)存區(qū)域,僅當(dāng)子進程有write發(fā)生時候,才會把改動的區(qū)域copy到子進程新的地址空間,這就是copy-on-write技術(shù),它極大的提高了創(chuàng)建進程的速度。

Linux的線程實現(xiàn)

  

  Linux線程是通過進程來實現(xiàn)。Linux kernel為進程創(chuàng)建提供一個clone()系統(tǒng)調(diào)用,clone的參數(shù)包括如 CLONE_VM, CLONE_FILES, CLONE_SIGHAND 等。通過clone()的參數(shù),新創(chuàng)建的進程,也稱為LWP(Lightweight process)與父進程共享內(nèi)存空間,文件句柄,信號處理等,從而達到創(chuàng)建線程相同的目的。

Linux 2.6的線程庫叫NPTL(Native POSIX Thread Library)。POSIX thread(pthread)是一個編程規(guī)范,通過此規(guī)范開發(fā)的多線程程序具有良好的跨平臺特性。盡管是基于進程的實現(xiàn),但新版的NPTL創(chuàng)建線程的效率非常高。一些測試顯示,基于NPTL的內(nèi)核創(chuàng)建10萬個線程只需要2秒,而沒有NPTL支持的內(nèi)核則需要長達15分鐘。

在Linux 2.6之前,Linux kernel并沒有真正的Thread支持,一些Thread library都是在clone()基礎(chǔ)上的一些基于user space的封裝,因此通常在信號處理、進程調(diào)度(每個進程需要一個額外的調(diào)度線程)及多線程之間同步共享資源等方面存在一定問題。為了解決這些問題,當(dāng)年IBM曾經(jīng)開發(fā)一套NGPT(Next Generation POSIX Threads), 效率比 LinuxThreads有明顯改進,但由于NPTL的推出,NGPT也完成了相關(guān)的歷史使命并停止了開發(fā)。

NPTL的實現(xiàn)是在kernel增加了futex(fast userspace mutex)支持用于處理線程之間的sleep與wake。futex是一種高效的對共享資源互斥訪問的算法。kernel在里面起仲裁作用,但通常都由進程自行完成。

NPTL是一個1×1的線程模型,即一個線程對于一個操作系統(tǒng)的調(diào)度進程,優(yōu)點是非常簡單。而其他一些操作系統(tǒng)比如Solaris則是MxN的,M對應(yīng)創(chuàng)建的線程數(shù),N對應(yīng)操作系統(tǒng)可以運行的實體。(N<M),優(yōu)點是線程切換快,但實現(xiàn)稍復(fù)雜。

信號

進程接收信號有兩種:同步和異步。同步信號比如SEGILL(非法訪問), SIGSEGV(segmentation fault)等。發(fā)生此類信號之后,系統(tǒng)會立即轉(zhuǎn)到內(nèi)核陷阱處理程序,因此同步信號也稱為陷阱。異步信號如kill, lwp_kill, sigsend等調(diào)用產(chǎn)生的都是,異步信號也稱為中斷。

kill <pid> 調(diào)用的是 SIGTERM, 此信號可以被捕獲和忽略。

kill -9 <pid> 調(diào)用的是 SIGKILL, 殺掉進程,不能被捕獲和忽略。

SIGHUP是在終端被斷開時候調(diào)用,如果信號沒有被處理,進程會終止。這就是為什么突然斷網(wǎng)剛通過遠程終端啟動的進程都終止的原因。防止的方法是在啟動的命令前加上 nohup 命令來忽略 SIGHUP信號。如 nohup ./startup.sh &

很多應(yīng)用程序通常捕獲SIGHUP用來實現(xiàn)一些自定義特性,比如通過控制臺傳遞信號讓正在運行的程序重新加載配置文件,避免重啟帶來的停止服務(wù)的副作用。可惜的是,在java中沒法直接使用這一功能,SUN JVM沒有官方的signal支持,盡管它已經(jīng)可以實現(xiàn),詳情可參看Singals and Java.

另外有個有趣的現(xiàn)象是 zombie 狀態(tài)的進程 kill/kill -9 都沒有任何作用,這是由于進程本身已經(jīng)不存在,所以沒有相應(yīng)的進程來處理signal, zombie狀態(tài)的進程只是kernel中的進程描述符及相關(guān)數(shù)據(jù)結(jié)構(gòu)沒有釋放,但進程實體已經(jīng)不存在了。

關(guān)于僵尸進程,也可參看下酷殼上的這篇Linux 的僵尸(zombie)進程,從程序的角度解釋了相關(guān)原理。


發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 宿迁市| 临泉县| 新化县| 武宣县| 军事| 安陆市| 洪湖市| 新民市| 安国市| 涡阳县| 宁明县| 双流县| 襄城县| 西盟| 内江市| 邢台市| 珲春市| 开江县| 蓝山县| 邛崃市| 平潭县| 永泰县| 会泽县| 冕宁县| 颍上县| 蓬安县| 江源县| 蕲春县| 邻水| 普安县| 寿阳县| 郸城县| 虞城县| 察隅县| 广宗县| 白朗县| 监利县| 甘孜| 茌平县| 酉阳| 合肥市|