卖逼视频免费看片|狼人就干网中文字慕|成人av影院导航|人妻少妇精品无码专区二区妖婧|亚洲丝袜视频玖玖|一区二区免费中文|日本高清无码一区|国产91无码小说|国产黄片子视频91sese日韩|免费高清无码成人网站入口

linux系統(tǒng)怎么把聲音圖標(biāo)顯示出來 Linux文件讀寫執(zhí)行權(quán)限的三種標(biāo)志符號依次是?

Linux文件讀寫執(zhí)行權(quán)限的三種標(biāo)志符號依次是?對應(yīng)的三種符號分別是 r 可讀w 可寫入x 可執(zhí)行nv硬盤在linux如何查看?可以先將nv圖標(biāo)選中變黑,再點(diǎn)右鍵中的查看,這樣就可以查看到硬盤里的內(nèi)容

Linux文件讀寫執(zhí)行權(quán)限的三種標(biāo)志符號依次是?

對應(yīng)的三種符號分別是 r 可讀w 可寫入x 可執(zhí)行

nv硬盤在linux如何查看?

可以先將nv圖標(biāo)選中變黑,再點(diǎn)右鍵中的查看,這樣就可以查看到硬盤里的內(nèi)容了。

linux聲音圖標(biāo)不見了?

原因就是桌面系統(tǒng)中與用戶交互的程序沒有啟動,而且不同的桌面系統(tǒng)的交互系統(tǒng)程序還不一樣, 這個就很麻煩了。 需要找出交互程序,并且在開機(jī)時設(shè)置自動啟動。

Linux系統(tǒng)是如何創(chuàng)建進(jìn)程的?聽說這一過程是用C語言clone函數(shù)實(shí)現(xiàn)的?

謝邀。

我之前兩節(jié)文章簡要地從C語言源代碼層面討論了Linux系統(tǒng)中進(jìn)程的基本概念,我們知道了Linux內(nèi)核如何描述和記錄進(jìn)程的資源,以及進(jìn)程的五種基本狀態(tài)和進(jìn)程的家族樹。事實(shí)上,就進(jìn)程管理而言,Linux還是有一些獨(dú)特之處的。

Linux 系統(tǒng)中的進(jìn)程創(chuàng)建許多操作系統(tǒng)都提供了專門的進(jìn)程產(chǎn)生機(jī)制,比較典型的過程是:首先在內(nèi)存新的地址空間里創(chuàng)建進(jìn)程,然后讀取可執(zhí)行程序,裝載到內(nèi)存中執(zhí)行。

Linux 系統(tǒng)創(chuàng)建線程并未使用上述經(jīng)典過程,而是將創(chuàng)建過程拆分到兩組獨(dú)立的函數(shù)中執(zhí)行:fork() 函數(shù)和 exec() 函數(shù)族。

基本流程是這樣的:首先,fork() 函數(shù)拷貝當(dāng)前進(jìn)程創(chuàng)建子進(jìn)程。產(chǎn)生的子進(jìn)程與父進(jìn)程的區(qū)別僅在與 PID 與 PPID 以及某些資源和統(tǒng)計(jì)量,例如掛起的信號等。準(zhǔn)備好進(jìn)程運(yùn)行的地址空間后,exec() 函數(shù)族負(fù)責(zé)讀取可執(zhí)行程序,并將其加載到相應(yīng)的位置開始執(zhí)行。

Linux 系統(tǒng)創(chuàng)建進(jìn)程使用的這兩組函數(shù)效果與其他操作系統(tǒng)的經(jīng)典進(jìn)程創(chuàng)建效果是相似的,可能有讀者會覺得這么做會讓進(jìn)程創(chuàng)建過于繁瑣,其實(shí)不是的,Linux 這么做的其中一個原因是為了提高代碼的復(fù)用率,這得益于 Linux 高度概括的抽象,無需再額外設(shè)計(jì)一套機(jī)制用于創(chuàng)建進(jìn)程。

“寫時拷貝”早期 Linux 中的 fork() 函數(shù)直接把父進(jìn)程的所有資源賦值給創(chuàng)建出的子進(jìn)程,這樣的機(jī)制自然是簡單的,但是效率卻比較低下。

原因是顯而易見的:子進(jìn)程并不一定要使用父進(jìn)程的資源,或者子進(jìn)程可能僅需以只讀的訪問父進(jìn)程的資源,這時“拷貝一份資源”就純屬多余的開銷了。

針對這樣的問題,Linux 后續(xù)版本中的 fork() 函數(shù)開始采用“寫時拷貝”機(jī)制。寫時拷貝技術(shù)可以將拷貝需求延遲,甚至免除拷貝,減小開銷。

具體來說就是,Linux 在調(diào)用 fork() 創(chuàng)建子進(jìn)程時,并不著急拷貝整個進(jìn)程地址空間,而是暫時讓父子進(jìn)程以只讀的共享同一個拷貝??截悇幼髦辉谧舆M(jìn)程需要寫入時才會發(fā)生,以確保各個進(jìn)程有自己獨(dú)立的內(nèi)存空間。

如果子進(jìn)程用不到或者只需要讀取共享空間數(shù)據(jù),那么拷貝動作就被省去了,Linux 就減小了開銷。例如,系統(tǒng)調(diào)用 fork() 后立即調(diào)用 exec(),此時 exec() 會加載新的映像覆蓋 fork() 的地址空間,拷貝動作完全可以省去。

事實(shí)上,fork() 函數(shù)的實(shí)際開銷就是復(fù)制父進(jìn)程的頁表以及給子進(jìn)程創(chuàng)建唯一的進(jìn)程描述符。在大多數(shù)情況下,Linux 創(chuàng)建進(jìn)程后都會馬上運(yùn)行新的可執(zhí)行程序,因此“寫時拷貝”機(jī)制可以避免相當(dāng)多的數(shù)據(jù)拷貝。創(chuàng)建進(jìn)程速度快是 Linux 系統(tǒng)的一個特征,因此“寫時拷貝”是一種相當(dāng)重要的優(yōu)化。

創(chuàng)建進(jìn)程時,內(nèi)存地址空間里常常包含數(shù)十 MB 的數(shù)據(jù),如果每創(chuàng)建一次進(jìn)程,就拷貝一次數(shù)據(jù),開銷顯然是非常大的。

fork() 函數(shù)Linux 中的 fork() 函數(shù)其實(shí)是基于 clone() 實(shí)現(xiàn)的,clone() 函數(shù)可以通過一系列參數(shù)標(biāo)志指定父子進(jìn)程需要共享的資源,在 Linux 中輸入 man 命令可以查看 clone() 函數(shù)的C語言原型,以及相關(guān)的參數(shù)標(biāo)志:在Linux中,fork() 函數(shù)最終調(diào)用了 do_fork() 函數(shù),它的C語言代碼如下,請看(do_fork() 函數(shù)的C語言代碼比較長,下面面只列出了一部分):

do_fork() 函數(shù)完成了進(jìn)程創(chuàng)建的大部分工作,從相關(guān)的C語言源代碼可以看出,它調(diào)用了 copy_process() 函數(shù),copy_process() 函數(shù)的C語言源代碼如下,請看:copy_process() 函數(shù)的代碼也是比較長的,在我手上的Linux系統(tǒng)中,達(dá)到了近 400 行,不過代碼的整體邏輯是清晰的:

(1)copy_process() 函數(shù)首先檢查了一些標(biāo)志位,接著調(diào)用 dup_task_struct() 函數(shù)為新進(jìn)程創(chuàng)建內(nèi)核棧,以及上一節(jié)提到的 thread_info 和 task_struct 結(jié)構(gòu):

創(chuàng)建后,接下來的 arch_dup_task_struct() 函數(shù)會將 orig 結(jié)構(gòu)拷貝給新創(chuàng)建的結(jié)構(gòu),查看相關(guān)C語言代碼,這一過程是清晰的:此時子進(jìn)程和父進(jìn)程的描述符是完全相同的。

(2)接下來,需要檢查一些標(biāo)志位和統(tǒng)計(jì)信息,相關(guān)的C語言代碼如下,請看:

(3)將一些統(tǒng)計(jì)量清零,以及初始化一些區(qū)別成員,此時雖然新進(jìn)程的 task_struct 結(jié)構(gòu)體大多成員未被修改,但是父子進(jìn)程已經(jīng)有所區(qū)別。這一過程的相關(guān)C語言代碼片段如下,請看:

(4)將新創(chuàng)建的子進(jìn)程狀態(tài)設(shè)置為 TASK_UNINTERRUUPTIBLE,確保其暫時不會被投入運(yùn)行,這一過程的C語言代碼相對簡單。(5)調(diào)用 alloc_pid() 函數(shù)為新進(jìn)程分配一個獨(dú)一無二的 pid,相關(guān)C語言代碼如下,請看:

(6)根據(jù) clone() 函數(shù)的參數(shù)標(biāo)志位,拷貝或共享已經(jīng)打開的文件、文件系統(tǒng)、信號處理函數(shù)、進(jìn)程地址空間等資源,例如下面這段C語言代碼:(7)將為新進(jìn)程創(chuàng)建的 task_struct 結(jié)構(gòu)體的指針返回給調(diào)用者,也即 do_fork() 函數(shù)。此時新創(chuàng)建的進(jìn)程還沒有被投入運(yùn)行。

現(xiàn)在回到 do_fork() 函數(shù)。如果調(diào)用 clone() 函數(shù)時,沒有傳遞 CLONE_STOPPED 參數(shù),新創(chuàng)建的進(jìn)程將被喚醒,并投入運(yùn)行,這一過程的C語言代碼如下:到這里,一個新的進(jìn)程就被 Linux 創(chuàng)建完畢了。

Linux 內(nèi)核有意讓新創(chuàng)建的子進(jìn)程先運(yùn)行,因?yàn)樽舆M(jìn)程常常會立即調(diào)用 exec() 函數(shù)加載新的程序到內(nèi)存中運(yùn)行,這樣就避免了寫時拷貝的額外開銷。如果父進(jìn)程首先執(zhí)行,顯然極有可能開始往地址空間寫入操作,導(dǎo)致拷貝動作發(fā)生。

小結(jié)本節(jié)詳細(xì)的從C語言代碼層面分析了Linux內(nèi)核創(chuàng)建進(jìn)程的過程,可見,即使是復(fù)雜的操作系統(tǒng)代碼,也是通過一系列基本C語言語法和函數(shù)實(shí)現(xiàn)的。那么,Linux 是如何創(chuàng)建線程的呢?之前我們曾經(jīng)提到,Linux 系統(tǒng)并不特別區(qū)分進(jìn)程和線程,線程其實(shí)是一種特殊的進(jìn)程,Linux 是如何實(shí)現(xiàn)這一“特殊”過程的呢?敬請關(guān)注。