1 進程總覽
進程是對邏輯的抽象,我們從作業系統的書籍中對進程有了很多的認識,但是對進程的實現可能不太了解,這篇文章試著解釋一下關於進程實現的大致原理。
進程的實現,其實和我們平常寫程式碼的時候一樣,例如我們要表示一個東西,我們會定義一個資料結構。進程也不例外。所以進程的本質就是一個資料結構,他保存了一系列的資料。作業系統以數組或鍊錶的形式和全部的進程管理起來。進程可以說分為兩種
1 系統初始化時第一個進程,
2 除了第一個進程外的其他進程,他們都是由fork或fork execute系統呼叫創建出來的。
我們先來看看進程的結構體都有什麼資訊。

以上就是表示進程的結構體中主要的資訊。那麼一個結構體就是表示一個流程。我們知道fork是以父進程為模組,複製一份父進程的結構體,然後修改某些欄位。就變成了一個新的進程。如果呼叫execute的話,就是進一步修改複製出來的結構體中的欄位(例如頁表、程式碼片段、資料段)。並且從硬碟載入相應的資料到記憶體。那麼第一個進程是如何產生的呢?因為進程只是一個結構體,所以如果我們預先定義了一個結構體,那就可以不透過fork的形式來創建一個進程了。
2 進程的執行
當系統建立一個行程之後,會設定cs:ip暫存器的值,如果是fork,則ip就是fork函數後面的語句的ip位址。如果是execute則ip位址由編譯器指定。不管怎樣,當行程開始執行的時候,cpu就會解析cs:ip拿到一條指令去執行。那麼cs:ip是如何被解析的呢?
執行進程的時候,tss選擇子(GDT索引)被載入到tss暫存器,然後把tss裡的上下文也載入到對應的暫存器,例如cr3,ldt選擇子。根據tss資訊中的ldt索引首先從GDT找到進程ldt結構體資料的首地址,然後根據當前段的屬性,例如代碼段,則從cs中取得選擇子,系統從ldt表中取得進程線性空間的首地址、限長、權限等資訊。用線性位址的首位址加上ip中的偏移,得到線性位址,然後再透過頁目錄和頁表得到實體位址,物理位址還沒有分配則進行缺頁異常等處理。
3 進程的暫停與喚醒
進程的掛起、阻斷、多進程。這些概念我們平常聽得比較多,現在我們來看看他是實現是怎樣的。進程的掛起,或者說阻塞分為兩種。
1 主動掛起。透過sleep讓進程間歇性掛起。 sleep的原理之前有分析過,就不再分析。大概的原理
就是設定一個定時器,到期後喚醒進程。
修改行程為掛起狀態,等待喚醒。
2 被動掛起。
被動掛起的場景比較多,主要是行程申請一個資源,但是資源沒有滿足條件,則行程被作業系統掛起。比如我們讀一個管道的時候。管道沒有資料可讀,則進程被掛起。插入到管道的等待隊列。

當管道有內容寫入的時候,流程就會被喚醒。進程被掛起(分為可被訊號喚醒和不能被訊號喚醒兩種)和喚醒的實現。
<code>// 当前进程挂载到睡眠队列p中,p指向队列头指针的地址<br>void sleep_on(struct task_struct **p)<br>{<br> struct task_struct *tmp;<br><br> if (!p)<br> return;<br> if (current == &(init_task.task))<br> panic("task[0] trying to sleep");<br> /*<br> *p为第一个睡眠节点的地址,即tmp指向第一个睡眠节点<br> 头指针指向当前进程,这个版本的实现没有采用真正链表的形式,<br> 他通过每个进程在栈中的临时变量形成一个链表,每个睡眠的进程,<br> 在栈里有一个变量指向后面一个睡眠节点,然后把链表的头指针指向当前进程,<br> 然后切换到其他进程执行,当被wake_up唤醒的时候,wake_up会唤醒链表的第一个<br> 睡眠节点,因为第一个节点里保存了后面一个节点的地址,所以他唤醒后面一个节点,<br> 后面一个节点以此类推,从而把整个链表的节点唤醒,这里的实现类似nginx的filter,<br> 即每个模块保存后面一个节点的地址,然后把全局指针指向自己。<br> */<br> tmp = *p;<br> *p = current;<br> // 不可中断睡眠只能通过wake_up唤醒,即使有信号也无法唤醒<br> current->state = TASK_UNINTERRUPTIBLE;<br> // 进程调度<br> schedule();<br> // 唤醒后面一个节点<br> if (tmp)<br> tmp->state=0;<br>}<br><br>// 唤醒队列中的第一个节点,并清空链表,因为第一个节点会向后唤醒其他节点<br>void wake_up(struct task_struct **p)<br>{<br> if (p && *p) {<br> (**p).state=0;<br> *p=NULL;<br> }<br>}</code>
我們發現,進程的實現,跟我們平時寫程式碼差不多,就是定義資料結構,然後實作操作資料結構的演算法。當然,因為涉及硬體底層,作業系統的實作比我們的程式碼複雜得多。
以上是意思?請提供更多上下文。的詳細內容。更多資訊請關注PHP中文網其他相關文章!

JVM的工作原理是將Java代碼轉換為機器碼並管理資源。 1)類加載:加載.class文件到內存。 2)運行時數據區:管理內存區域。 3)執行引擎:解釋或編譯執行字節碼。 4)本地方法接口:通過JNI與操作系統交互。

JVM使Java實現跨平台運行。 1)JVM加載、驗證和執行字節碼。 2)JVM的工作包括類加載、字節碼驗證、解釋執行和內存管理。 3)JVM支持高級功能如動態類加載和反射。

Java應用可通過以下步驟在不同操作系統上運行:1)使用File或Paths類處理文件路徑;2)通過System.getenv()設置和獲取環境變量;3)利用Maven或Gradle管理依賴並測試。 Java的跨平台能力依賴於JVM的抽象層,但仍需手動處理某些操作系統特定的功能。

Java在不同平台上需要進行特定配置和調優。 1)調整JVM參數,如-Xms和-Xmx設置堆大小。 2)選擇合適的垃圾回收策略,如ParallelGC或G1GC。 3)配置Native庫以適應不同平台,這些措施能讓Java應用在各種環境中發揮最佳性能。

Osgi,Apachecommonslang,JNA和JvMoptionsareeForhandlingForhandlingPlatform-specificchallengesinjava.1)osgimanagesdeppedendendencenciesandisolatescomponents.2)apachecommonslangprovidesitorityfunctions.3)

JVMmanagesgarbagecollectionacrossplatformseffectivelybyusingagenerationalapproachandadaptingtoOSandhardwaredifferences.ItemploysvariouscollectorslikeSerial,Parallel,CMS,andG1,eachsuitedfordifferentscenarios.Performancecanbetunedwithflagslike-XX:NewRa

Java代碼可以在不同操作系統上無需修改即可運行,這是因為Java的“一次編寫,到處運行”哲學,由Java虛擬機(JVM)實現。 JVM作為編譯後的Java字節碼與操作系統之間的中介,將字節碼翻譯成特定機器指令,確保程序在任何安裝了JVM的平台上都能獨立運行。

Java程序的編譯和執行通過字節碼和JVM實現平台獨立性。 1)編寫Java源碼並編譯成字節碼。 2)使用JVM在任何平台上執行字節碼,確保代碼的跨平台運行。


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

Dreamweaver Mac版
視覺化網頁開發工具

mPDF
mPDF是一個PHP庫,可以從UTF-8編碼的HTML產生PDF檔案。原作者Ian Back編寫mPDF以從他的網站上「即時」輸出PDF文件,並處理不同的語言。與原始腳本如HTML2FPDF相比,它的速度較慢,並且在使用Unicode字體時產生的檔案較大,但支援CSS樣式等,並進行了大量增強。支援幾乎所有語言,包括RTL(阿拉伯語和希伯來語)和CJK(中日韓)。支援嵌套的區塊級元素(如P、DIV),

SublimeText3 Linux新版
SublimeText3 Linux最新版

Atom編輯器mac版下載
最受歡迎的的開源編輯器

PhpStorm Mac 版本
最新(2018.2.1 )專業的PHP整合開發工具