您好,登錄后才能下訂單哦!
本篇內容主要講解“怎么理解web進程和線程”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“怎么理解web進程和線程”吧!
進程和線程是操作系統里很重要的概念,但是所有的東西都會落實到代碼。看起來很復雜的進程線程,其實在操作系統的代碼里。也只是一些數據結構和算法。只不過他比一般的數據結構和算法可能復雜點。但是學習方法還是一樣的,就是深入源碼,一探究竟。
進程在操作系統里,是用一個task_struct結構體表示的。因為操作系統是大部分是用c語言實現的,沒有對象這個概念。如果我們用高級語言來理解的話,每個進程就是一個對象。每次新建一個進程,就是新建一個對象。task_struct結構體可以說是類的定義。我們看一下一個task_struct的定義。
操作系統里會維護一個task_struct數組或者鏈表來記錄當前系統中所有的進程。每次新建一個進程的時候,就會往里面追加一個task_struct結構體,每次銷毀一個進程的時候,該進程的父進程會刪除對應的task_struct。
操作系統的運作,很大程度上是由時鐘驅動的,電腦中會有一個硬件間歇性地產生時鐘中斷。中斷間隔是由操作系統初始化該硬件時決定的(定時器也是由該硬件驅動的,我們在應用層使用的定時器功能,歸根到底還是使用系統的定時器去實現的)。每次時鐘中斷的時候如果當前執行的進程時間片已到,則會發生進程調度。另外進程阻塞的時候,也會發生進程調度。被調度到的進程,系統就會把task_struct里的tss信息加載到cpu。包括當前執行的代碼位置,各種寄存器的值。然后就完成了進程的切換。
每次時鐘中斷的時候,時鐘中斷處理程序都會累加當前進程的執行時間,我們平時查看的進程的執行時間,這些數據就是由這些字段記錄的。一個進程在內核態和用戶態下執行的時間,是分開計算的。
task_struct中用三個字段實現了信號相關的功能,一個是signal,記錄了進程收到的信號,按位計算。blocked就是記錄當前進程不接收哪些信號。sigaction則是記錄每個信號對應的處理函數,和signal一一對應。每次我們調用kill的時候,其實就是修改signal字段的值。然后在某些時機下,系統會執行sigaction里對應的函數。這些時機包括系統調用返回,時鐘中斷處理程序返回、還有其他的硬件中斷返回等等。
task_struct用一個字段state記錄了進程當前的狀態,exit_code記錄進程退出時的退出碼。
當前進程的根目錄、工作目錄。我們平時在進程里打開一個文件的時候,如果沒有寫明絕對路徑,系統就會以工作目錄為基礎,加上我們傳的相對路徑拼出絕對路徑。從而找到文件。另外filp字段是維護進程打開的文件信息。我們平時拿到的文件描述符就是filp字段的索引。他會逐步找到底層對應的文件或者socket。executable是保存進程對應的二進制文件所在的文件信息。我們都知道程序加載到內存變成進程。executable保存的就是程序對應的文件的信息。
task_struct里用uid、euid、gid、egid等字段記錄進程的權限信息。
pid字段記錄了當前進程的id,father記錄了父進程的id。pgrp,session,leader分別是組id,會話id,是不是會話leader。多個進程組成一個組,多個組組成一個會話。如果一個進程是這個組或者會話的leader,則他的id會成為組或者會話的id,比如
組1有進程a的id是1(組leader、會話leader)進程b的id是2。
組2有進程c的id是3(組leader),進程d的id是4。
所有進程在一個會話,則組1的所有進程的組id和會話id都是1。組2所有進程的組id是3,會話id是1。
tss_struct和desc_struct結構體記錄了進程執行的上下文,每次進程切換的時候,如果是被調度執行,則上下文加載到cpu和對應的硬件中,如果是被掛起,則cpu和硬件的信息保存到上下文。下次執行的時候恢復。
以上就是一個進程所具有的一些屬性。我們發現,進程也沒有那么難以理解,好比我們平時定義一個人,他有名字,身高,年齡屬性一樣。每個對象,他都有屬于自己的一些屬性。
下面我們再來看一下線程。相比進程,線程對很多同學來說可能更難理解。其實對于操作系統來說,沒有單獨去實現線程這個概念,操作系統把進程和線程抽象成執行上下文。可以說他們是一個東西。但是他們又有一點點區別。我們以linuxthreads線程庫為例。了解一下線程是什么。我們知道fork可以新建一個進程。但是這個進程太重了,盡管有些屬性是可以共享的。所以操作系統重新實現了一個系統調用clone。他支持更細粒度的屬性共享。所以我們稱線程是輕量級的進程。顧名思義,線程也是進程,但是他是輕量級的,因為他很多屬性都是共享于父進程(父線程)的。共享的屬性可以通過clone函數的參數來控制。當我們新建一個線程的時候,系統里會新建一個進程。clone函數會把棧的位置和代碼執行的位置(就是我們傳進去的函數)告訴系統。系統會從我們定義的函數開始執行。大概如下。
到此,相信大家對“怎么理解web進程和線程”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。