1. 程式人生 > >Linux下的程序1——程序概念,程序切換,上下文切換,虛擬地址空間

Linux下的程序1——程序概念,程序切換,上下文切換,虛擬地址空間

程序概述

  當一個可執行程式在現代系統上執行時,作業系統會提供一種假象——好像系統上只有這個程式在執行,看上去只有這個程式在使用處理器,主存和IO裝置。
  處理器看上去就像在不間斷的一條接一條的執行程式中的指令,即改程式的程式碼和資料是系統儲存器中唯一的物件。這些假象是通過程序的概念來實現的。
  程序是作業系統對一個正在執行的程式的一種抽象。在一個系統上可以同時執行多個程序,而每個程序都好像在獨佔的使用硬體。而併發執行則是說一個程序的指令和另一個程序的指令是交錯執行的。
  在大多數系統中,需要執行的程序數是多於可以執行他們的CPU個數的。
  傳統系統在一個時刻只能執行一個程式,而現在的多核處理器同時能夠執行多個程式。
  無論是在多核還是單核系統中,一個CPU看上去都像是在併發的執行多個程序,這是通過處理器在程序間切換來實現的。
  作業系統實現這種交錯執行的機制稱為上下文切換。

  作業系統保持跟蹤程序執行所需的所有狀態資訊,這種狀態,也就是上下文,它包括許多資訊,例如PC和暫存器檔案的當前值,以及主存的內容。
  在任何一個時刻,單處理器系統都只能執行一個程序的程式碼。
  當作業系統決定要把控制權從當前程序轉移到某個新程序時,就會進行上下文切換即儲存當前程序的上下文,恢復新程序的上下文,然後將控制權傳遞到新程序,新程序就會從上次停止的地方開始

  深入計算機系統一書中對上下文切換的表達如下圖:
  這裡寫圖片描述

  如果現在有兩個併發的程序:外殼程序和hello程序。
  開始只有外殼程序在執行,即等待命令列上的輸入,當我們讓他執行hello程式時,外殼通過呼叫一個專門的函式,即系統呼叫

,來執行我們的請求,系統呼叫會將控制權傳遞給作業系統。
  作業系統儲存外殼程序的上下文,建立一個新的hello程序及其上下文,然後將控制權傳遞給新的hello程序。
  hello程序終止後,作業系統恢復外殼程序的上下文,並將控制權傳回給他,外殼程序將繼續等待下一個命令列輸入。

  這裡很重要的一個思想是:一個程序是某種型別的一個活動,他有程式,輸入,輸出以及狀態。單個處理器可以被若干程序共享,它使用某種排程演算法決定何時停止一個程序, 並轉而為另一個程序提供服務。
  

程序

   程序的經典定義就是一個執行中的程式的例項。
  系統中的每個程式都是執行在某個程序的上下文中的。
  上下文是由程式正確執行所需的狀態組成的,這個狀態包括存放在儲存器中的程式的程式碼和資料,他的棧,通用目的暫存器的內容,程式計數器,環境變數以及開啟檔案描述符的集合。

  每次使用者通過向外殼輸入一個可執行目標檔案的名字,並執行一個程式時,外殼就會建立一個新的程序,然後在這個新程序的上下文中執行這個可執行目標檔案。
  應用程式也能夠建立新程序,且在這個新程序的上下文中執行他們自己的程式碼或其他應用程式。
  程序提供給應用程式的關鍵抽象:
  

  • 一個獨立的邏輯控制流,它提供一個假象,好像我們的程式獨佔的使用處理器
  • 一個私有的地址空間,它提供一個假象,好像我們的程式獨佔地使用儲存器系統

      而實際上,程序是輪流使用處理器的。
      每個程序執行他的流的一部分,然後被搶佔,即暫時掛起,然後輪到其他程序。
      對於一個執行在這些程序之一的上下文中的程式,他看上去就像是在獨佔的使用處理器。

使用者模式和核心模式

  為了使操作系用核心提供一個無懈可擊的程序抽象,處理器必須提供一種機制,限制一個應用可以執行的指令以及它可以訪問的地址空間範圍。
  處理器通常是用某個控制暫存器中的一個模式位來提供這種功能的,該暫存器描述了程序當前享有的特權。
  當設定了模式位時,程序就執行在核心模式中,即超級使用者模式。
  一個執行在核心模式的程序可以執行指令集中的任何指令,並且可以訪問系統中任何儲存器位置。
  沒有設定模式位時,程序就執行在使用者模式中。使用者模式中的程序不允許執行特權指令,比如停止處理器,改變模式位,或者發起一個I/O操作。也不允許使用者模式中的程序直接引用地址空間中核心區內的程式碼和資料。
  執行應用程式程式碼的程序初始時是在使用者模式中的。
  程序從使用者模式變為核心模式的唯一方法是通過諸如中斷,故障或者陷入系統呼叫這樣的異常,當異常發生時,控制傳遞到異常處理程式,處理器將模式從使用者模式變為核心模式。
  處理程式執行在核心模式中,當他返回到應用程式程式碼時,處理器就把模式從核心模式改回到使用者模式。

上下文切換

  作業系統核心使用一種稱為上下文切換的較高層形式的控制流來實現多工。
  核心為每一個程序維持一個上下文。
  上下文就是核心重新啟動一個被搶佔的程序所需的狀態。他有一些物件的值組成,這些物件包括:  

  • 通用目的暫存器
  • 浮點暫存器
  • 程式計數器
  • 使用者棧
  • 狀態暫存器
  • 核心棧
  • 各種核心資料結構

      核心資料結構,比如描繪地址空間的頁表,包含有關當前程序資訊的程序表,以及包含程序已開啟檔案的資訊的檔案表。
      在程序執行的某些時刻,核心可以決定搶佔當前程序,並重新開始一個先前被搶佔的程序。
      這種決定就叫做排程,是由核心中稱為排程器的程式碼處理的。
      當核心選擇一個新的程序執行時,我們就說核心排程了這個程序。在核心排程了一個新的程序執行後,他就搶佔當前程序,並使用一種稱為上下文切換的機制來將控制轉移到新的程序。
    上下文切換 

  • 儲存當前程序的上下文
  • 恢復某個先前被搶佔的程序被儲存的上下文
  • 將控制傳遞給這個新恢復的程序

      當核心代表使用者執行系統呼叫時,可能會發生上下文切換,如果系統呼叫因為等待某個時間發生而阻塞,那麼核心可以讓當前程序休眠,切換到另一個程序。
      比如:如果一個read系統呼叫請求一個磁碟訪問,核心可以選擇執行上下文切換,執行另外一個程序,而不是等待資料從磁碟到達。
      另一個例子是sleep系統呼叫,它顯式的請求讓呼叫程序休眠,一般而言,即使系統呼叫沒有阻塞,核心也可以決定執行上下文切換,而不是將控制返回給呼叫程序。
      中斷也可能引發上下文切換。

      比如,所有的系統都有某種產生週期性定時器中斷的機制,典型的為每一毫秒或每十毫秒,每次發生定時器中斷時,核心就能判定當前程序已經運行了足夠長時間了,並切換到一個新的程序。
      上下文簡單說來就是一個環境,相對於程序而言,就是程序執行時的環境

      具體來說就是各個變數和資料,包括所有的暫存器變數、程序開啟的檔案、記憶體資訊等。
      一個程序的上下文可以分為三個部分:使用者級上下文、暫存器上下文以及系統級上下文。

使用者級上下文: 正文、資料、使用者堆疊以及共享儲存區;
暫存器上下文: 通用暫存器、程式暫存器(IP)、處理器狀態暫存器(EFLAGS)、棧指標(ESP);
系統級上下文: 程序控制塊task_struct、記憶體管理資訊(mm_struct、vm_area_struct、pgd、pte)、核心棧

  當發生程序排程時,進行程序切換就是上下文切換(context switch).作業系統必須對上面提到的全部資訊進行切換,新排程的程序才能執行。

  而系統呼叫進行的是模式切換(mode switch)。模式切換與程序切換比較起來,容易很多,而且節省時間,因為模式切換最主要的任務只是切換程序暫存器上下文的切換。
  程序上下文主要是異常處理程式和核心執行緒。
  核心之所以進入程序上下文是因為程序自身的一些工作需要在核心中做。例如,系統呼叫是為當前程序服務的,異常通常是處理程序導致的錯誤狀態等。所以在程序上下文中引用current是有意義的。

  核心進入中斷上下文是因為中斷訊號而導致的中斷處理或軟中斷。而中斷訊號的發生是隨機的,中斷處理程式及軟中斷並不能事先預測發生中斷時當前執行的是哪個程序,所以在中斷上下文中引用current是可以的,但沒有意義。
  事實上,對於A程序希望等待的中斷訊號,可能在B程序執行期間發生。例如,A程序啟動寫磁碟操作,A程序睡眠後B程序在執行,當磁碟寫完後磁碟中斷訊號打斷的是B程序,在中斷處理時會喚醒A程序。

  核心可以處於兩種上下文:程序上下文和中斷上下文。

  在系統呼叫之後,使用者應用程式進入核心空間,此後核心空間針對使用者空間相應程序的代表就運行於程序上下文。非同步發生的中斷會引發中斷處理程式被呼叫,中斷處理程式就運行於中斷上下文
  中斷上下文和程序上下文不可能同時發生。

  運行於程序上下文的核心程式碼是可搶佔的,但中斷上下文則會一直執行至結束,不會被搶佔。
  因此,核心會限制中斷上下文的工作,不允許其執行如下操作:

  • (1)進入睡眠狀態或主動放棄CPU;

      由於中斷上下文不屬於任何程序,它與current沒有任何關係(儘管此時current指向被中斷的程序),所以中斷上下文一旦睡眠或者放棄CPU,將無法被喚醒。所以也叫原子上下文(atomic context)。

  • (2) 佔用互斥體

      為了保護中斷控制代碼臨界區資源,不能使用mutexes。如果獲得不到訊號量,程式碼就會睡眠,會產生和上面相同的情況,如果必須使用鎖,則使用spinlock。

  • (3) 執行耗時的任務;

      中斷處理應該儘可能快,因為核心要響應大量服務和請求,中斷上下文佔用CPU時間太長會嚴重影響系統功能。在中斷處理例程中執行耗時任務時,應該交由中斷處理例程底半部來處理。

  • (4) 訪問使用者空間虛擬記憶體。

  因為中斷上下文是和特定程序無關的,它是核心代表硬體執行在核心空間,所以在中斷上下文無法訪問使用者空間的虛擬地址

  • (5) 中斷處理例程不應該設定成reentrant(可被並行或遞迴呼叫的例程)。

    因為中斷髮生時,preempt和irq都被disable,直到中斷返回。所以中斷上下文和程序上下文不一樣,中斷處理例程的不同例項,是不允許在SMP上併發執行的。

  • (6)中斷處理例程可以被更高級別的IRQ中斷。

      如果想禁止這種中斷,可以將中斷處理例程定義成快速處理例程,相當於告訴CPU,該例程執行時,禁止本地CPU上所有中斷請求。這直接導致的結果是,由於其他中斷被延遲響應,系統性能下降。

虛擬儲存器——私有地址空間

  虛擬儲存器是一個抽象的概念,他為每一個程序提供了一個假象,即每個程序都在獨佔地使用主存。
  每個程序看到的是一致的儲存器,成為虛擬地址空間。
  在一臺有n位地址空間的機器上,地址空間是2的n次方個可能地址的集合,0,1,…,2^n - 1。
  一個程序為每個程式提供他自己的私有地址空間,一般而言,和這個空間中某個地址相關聯的那個儲存器位元組是不能被其他程序讀或者寫的,從這個意義上來說,這個地址空間是私有的。
  下圖是程序的虛擬地址空間圖示。
  這裡寫圖片描述
  

  地址空間頂部是保留給核心的,這個部分包含核心在代表程序執行指令時使用的程式碼,資料和棧,這對所有程序來說都是一樣的。地址空間的底部區域是保留給使用者程式的,包括通常的文字,資料,堆和棧段。
  圖中的地址是從下往上增大的

  每個程序看到的虛擬地址空間由大量準確定義的區構成,每個區都有專門的功能。
  1.程式程式碼和資料
  對於多有的程序來說,程式碼是從同一固定地址開始,緊接著的是和C全域性變數相對應的資料位置,程式碼和資料區是直接按照可執行目標檔案的內容初始化的。
  2.堆
  程式碼和資料區後緊隨著的是執行時堆。
  程式碼和資料區是在程序已開始執行時就被規定了大小,與此不同,當呼叫malloc和free這樣的C標準庫函式時,堆可以在執行時動態的擴充套件和收縮。
  3.共享庫
  在地址空間的中間部分是一塊用來存放像C標準庫和數學庫這樣共享庫的程式碼和資料的區域。
  4.棧
  位於使用者虛擬地址空間頂部的是使用者棧,編譯器用它來實現函式呼叫。和堆一樣,使用者棧在程式執行期間可以動態的擴充套件和收縮,特別是我們每次呼叫一個函式時,棧就會增長,從一個函式返回時,站就會收縮。
  5.核心虛擬儲存器
  核心總是駐留在記憶體中,是作業系統的一部分。
  地址空間頂部的區域是為核心保留的,不允許應用程式讀寫這個區域的內容或者直接呼叫核心程式碼定義的函式。

  一個系統中的程序是與其他程序共享CPU和主存資源的。
  然而,共享主存會導致記憶體不夠用的情況。
  為了有效的管理儲存器並且少出錯,現代系統提供了一種對主存的抽象概念,叫做虛擬儲存器(VM)。
  虛擬儲存器是硬體異常、硬體地址翻譯、主存、磁碟檔案和核心軟體的完美互動,他為每個程序提供了一個大的,一致的和私有的地址空間。
  虛擬儲存器提供了三個重要的能力:  

  • 1.它將主存看成是一個儲存在磁碟上的地址空間的快取記憶體,在主存中只儲存活動區域,並根據需要在磁碟和主存之間來回傳送資料,通過這種方式,它高效的使用了主存
  • 2.他為每個程序提供了一致的地址空間,從而簡化了儲存器管理
  • 3.他保護了每個程序的地址空間不被其他程序破壞

實體地址

  實體地址(Physical Address) 是指出目前CPU外部地址總線上的定址實體記憶體的地址訊號,是地址變換的最終結果地址。

  如果啟用了分頁機制,那麼線性地址會使用頁目錄和頁表中的項變換成實體地址。如果沒有啟用分頁機制,那麼線性地址就直接成為實體地址了。
  計算機系統的主存被組織成一個有M個連續的位元組大小的單元組成的陣列。每個位元組都有一個唯一的實體地址。
  第一個位元組的地址為0,接下來的位元組地址為1,再下一個為2.以此類推。給定這種簡單的結構,CPU訪問儲存器的最自然的方式就是使用實體地址。
  我們把這種方式叫做物理定址。
  當CPU執行載入指令時,他會生成一個有效實體地址,通過儲存器匯流排,把他傳遞給主存。主存取出從實體地址指定處開始的指定位元組,並將它返回給CPU,CPU會將它存放在一個暫存器裡。

虛擬地址

  使用虛擬定址時,CPU通過生成一個虛擬地址來訪問主存,這個虛擬地址在被送到儲存器之前先轉換成適當的實體地址。
  將一個虛擬地址轉換為實體地址的任務叫做地址翻譯。

  CPU晶片上叫做儲存器管理單元的專用硬體,利用存放在主存中的查詢表來動態翻譯虛擬地址,該表的內容是由作業系統管理的。
  
  在一個帶虛擬儲存器的系統中,CPU從一個有N=2^n個地址的地址空間中生成虛擬地址,這個地址空間稱為虛擬地址空間。

  一個地址空間的大小是由表示最大地址所需要的位數來描述的。
  例如:一個包含N=2^n個地址的虛擬地址空間就叫做一個n為地址空間。

邏輯地址

  邏輯地址(Logical Address) 是指由程式產生的與段相關的偏移地址部分。

  例如,你在進行C語言指標程式設計中,可以讀取指標變數本身值(&操作),實際上這個值就是邏輯地址,它是相對於你當前程序資料段的地址,不和絕對實體地址相干。
  應用程式設計師僅需與邏輯地址打交道,而分段和分頁機制對您來說是完全透明的,僅由系統程式設計人員涉及。應用程式設計師雖然自己可以直接操作記憶體,那也只能在作業系統給你分配的記憶體段操作。

線性地址

  線性地址(Linear Address) 是邏輯地址到實體地址變換之間的中間層。

  程式程式碼會產生邏輯地址,或者說是段中的偏移地址,加上相應段的基地址就生成了一個線性地址。 
  如果啟用了分頁機制,那麼線性地址可以再經變換以產生一個實體地址。若沒有啟用分頁機制,那麼線性地址直接就是實體地址。

程序的隔離

  地址空間分兩種: 

  • 虛擬地址空間
  • 實體地址空間
      實體地址空間是實實在在存在的,存在於計算機中,而且對於每一臺計算機來說只有唯一的一個,可以把物理空間想象成實體記憶體。
      虛擬地址空間是虛擬的,人們想象出來的地址空間,其實他就不存在,每個程序都有自己獨立的虛擬空間,而且每個程序只能訪問自己的地址空間,這樣就做到了程序的隔離。

分頁

  分頁的基本方法是把地址空間人為地等分成固定大小的頁,每一頁的大小有硬體決定,或硬體支援多種大小的頁,由作業系統選擇決定頁的大小。
  對整個系統來說,頁就是固定大小的。
  當我們把程序的虛擬地址空間按頁分割,把常用的資料和內碼表裝載到記憶體中,把不常用的程式碼和資料儲存在磁盤裡,當需要用到的時候再把它從磁盤裡取出來即可。
  這裡寫圖片描述
  如上圖所示:
  假設有兩個程序Process1和Process2,他們程序中的部分虛擬頁面被對映到了物理頁面。
  比如VP0.VP1和VP7對映到PP0,PP2和PP3,而有部分頁面卻在磁碟中,比如VP2和VP3位於磁碟的DP0,DP1中,另外還有一些頁面如VP4,VP5和VP6可能尚未被用到或訪問到,他們暫時處於未使用狀態。
  我們把虛擬空間的頁就叫做虛擬頁VP,把實體記憶體中的頁叫做物理頁PP,把磁碟中的頁叫做磁碟頁DP。
  我們可以看到虛擬空間的有些頁被對映到同一物理頁,這樣就可以實現記憶體共享。
  虛擬儲存的實現需要依靠硬體的支援,對於不同的CPU來說是不同的,但是幾乎所有的硬體都採用一個叫做MMU的部件來進行頁對映。
  在頁對映模式下,CPU發出的是虛擬地址,即我們程式看到的是虛擬地址,經過MMU轉換以後就變成了實體地址。

Linux虛擬儲存器系統

  Linux為每個程序維持了一個單獨的虛擬地址空間
  這裡寫圖片描述
  

共享區域

  如果虛擬儲存器系統可以整合到傳統的檔案系統中,那麼就能提供一種簡單而高效的把程式和資料載入到儲存器中的方法。
  在前面已經提到,程序這一抽象能夠為每個程序提供自己私有的虛擬地址空間,可以面授其他程序的錯誤讀寫。
  不過,許多程序有同樣的制度文字區域。
  例如,每個執行Unix外殼程式tcsh的程序都有相同的文字區域,而且,許多程式需要訪問只讀執行時庫程式碼相同的拷貝。
  例如,每個C程式都需要來自標準C庫的,像printf這樣的函式。
  那麼如果每個程序都在物理儲存器中保持這些常用程式碼的複製拷貝,那就是極端的浪費了。
  其實,儲存器對映給我們提供了一種清晰的機制,用來控制多個程序如何共享物件。
  一個物件可以被對映到虛擬儲存器的一個區域,要麼作為共享物件,要麼作為私有物件。
  如果一個程序將一個共享物件對映到他的虛擬地址空間的一個區域內,那麼這個程序對這個區域的任何寫操作,對於哪些也把這個共享物件對映到他們虛擬儲存器的其他程序而言也是可見的。
  而且,這些變化也會反映在磁碟上的原始物件中。

  另一方面,對一個對映到私有物件的區域做的改變,對於其他程序來說是不可見的,並且程序對這個區域所做的任何寫操作都不會反映在磁碟上的物件中。
  一個對映到共享物件的虛擬儲存器區域叫做共享區域,相反的叫做私有區域。

  假設程序1將一個共享物件對映到他的虛擬儲存器的一個區域中,現在假設程序2將同一個共享物件對映到他的地址空間,並不一定要和程序1在相同的虛擬地址處。
  這裡寫圖片描述
  因為每一個物件都有一個唯一的檔名,核心可以迅速的判定程序1已經映射了這個物件,而且可以使程序2中的頁表條目指向相應的物理頁面。
  關鍵點在於即使物件被對映到了多個共享區域,物理儲存器中也只需要存放共享物件的一個拷貝。

寫時拷貝技術

  私有物件是使用一種叫做寫時拷貝的巧妙技術被對映到虛擬儲存器中的。
  一個私有物件開始生命週期的方式基本上與共享物件的一樣,在物理儲存器中只儲存有私有物件的一份拷貝。
  這裡寫圖片描述
  上圖中,兩個程序將一個私有物件對映到他們虛擬儲存器的不同區域,但是共享這個物件的同一份物理拷貝。
  那麼怎樣體現是私有的呢?
  對於每個對映私有物件的程序,相應私有區域的頁表條目都被標記為只讀,並且區域結構被標記為私有的寫時拷貝。
  只要沒有程序試圖寫它自己的私有區域,他們就可以繼續共享物理儲存器中物件的一個單獨拷貝。
  然而,只要有一個程序師試圖寫私有區域內的某個頁面,那麼這個寫操作就會觸發一個保護故障。
  當故障處理程式注意到保護異常是由於程序試圖寫私有的寫時拷貝區域中的一個頁面而引起的,他就會在物理儲存器中建立這個頁面的一份新拷貝,更新頁表條目指向這個新拷貝,然後恢復這個頁面的可寫許可權,當故障處理程式返回時,CPU重新執行這個寫操作,現在在新建立的頁面上這個寫操作就可以執行了。
  這就是程序的寫時拷貝技術。

相關推薦

Linux程序1——程序概念程序切換上下文切換虛擬地址空間

程序概述   當一個可執行程式在現代系統上執行時,作業系統會提供一種假象——好像系統上只有這個程式在執行,看上去只有這個程式在使用處理器,主存和IO裝置。   處理器看上去就像在不間斷的一條接一條的執行程式中的指令,即改程式的程式碼和資料是系統儲存器中唯一的

Linux如何用/proc命令查詢程序狀態資訊——當前目錄記憶體佔用描述符等

參加阿里的面試,問到一個問題,如何在Linux下使用命令列查詢程序的狀態資訊,比如程序的當前目錄,程序的記憶體佔用等情況。當時的第一反應是使用top命令能夠得到所有的程序資訊。但是面試官好像不是很滿意,因此我回去之後查閱了相關的資料,發現可能他想問的/proc目錄,我這裡整

Linux通過源碼編譯安裝程序

安裝程序 configure 系統目錄 install 命令 com 需要 figure .com ASK: Linux下通過源碼編譯安裝程序(configure/make/make install的作用) configure Linux 平臺有各種不同的配置,安裝時需

LINUXC++程式設計如何獲得某程序的ID

#include <stdio.h> #include <stdlib.h> #include <unistd.h> using namespace std; pid_t getProcessPidByName(const char *proc_name) {

Linux啟動停止檢視殺死Tomcat程序

啟動 一般是執行tomcat/bin/startup.sh,sh tomcat/bin/startup.sh 停止 一般是執行 sh tomcat/bin/shutdown.sh指令碼命令 檢視 執行ps -ef |grep tomcat 輸出如下 sun 5144

linux的C語言開發(程序等待)

                【 宣告:版權所有,歡迎轉載,請勿用於商業用途。  聯絡信箱:feixiaoxing @163.com】    所謂程序等待,其實很簡單。前面我們說過可以用fork建立子程序,那麼這裡我們就可以使用wait函式讓父程序等待子程序執行結束後才開始執行。注意,為了證明父程序確實是等

linux的多執行緒/多程序同步/通訊機制

while (1) { //這個mutex主要是用來保證pthread_cond_wait的併發性 pthread_mutex_lock(&mtx); while (head == NULL) {

Linux 啟動、關閉tomcat 殺掉程序等命令

sun 5144 1 0 10:21 pts/1 00:00:06 /Java/jdk/bin/java -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djava.endorsed.dirs=/java/tomcat/co

linuxC 程式設計學習之多程序程式設計(一)

一、程序概念 程序是作業系統中資源分配的最小單位,而執行緒是排程的最小單位。 一個程序,主要包含三個元素: a)        一個可以執行的程式; b)        和該程序相關聯的全部資料(包括變數,記憶體空間,緩衝區等等); c)        程式的執行上下文(

系統技術非業餘研究 » Linux如何知道檔案被那個程序

晚上朔海同學問: 一個檔案正在被程序寫 我想檢視這個程序 檔案一直在增大 找不到誰在寫 使用lsof也沒找到 這個問題挺有普遍性的,解決方法應該很多,這裡我給大家提個比較直觀的方法。 linux下每個檔案都會在某個塊裝置上存放,當然也都有相應的inode, 那麼透過vfs.write我們就可以知道

Linux popen 函式引起的殭屍程序 defunct 以及解決辦法

        在使用 popen 函式的時候,如果不注意的話,可能會引起殭屍程序 defunct 的存在,雖然該程序不佔用記憶體和 CPU,但是會在程序任務管理樹上佔用一個寶貴的節點。這樣就造成了程序名額的資源浪費,所以一定得處理殭屍程序! 下面以 python 為例來

linux的執行緒ID和程序ID

 在描述執行緒ID和程序ID之前我們先來分清楚幾個概念: 1. 使用者級執行緒和核心級執行緒 什麼是使用者級執行緒? 使用者級執行緒核心的切換由使用者態程式自己控制核心切換,不需要

linux如何在shell中結束程序(ctrl+c\ctrl+z\ctrl+d\ctrl+\的用法)

ctrl-c:傳送 SIGINT 訊號給前臺程序組中的所有程序。常用於終止正在執行的程式; ctrl-z:傳送 SIGTSTP訊號給前臺程序組中的所有程序,常用於掛起一個程序; ctrl-d:不是傳送

關於在 Linux 多個不相干的程序互斥訪問同一片共享記憶體的問題

這裡的“不相干”,定義為: 這幾個程序沒有父子關係,也沒有 Server/Client 關係這一片共享記憶體一開始不存在,第一個要訪問它的程序負責新建也沒有額外的 daemon 程序能管理這事情 看上去這是一個很簡單的問題,實際上不簡單。有兩大問題: 程序在持有互斥鎖的

linux結束指定名稱的所有程序

1.kill -9 `ps -ef| grep ./videohandle| awk '{print $2}'` 功能:結束名為./videohandle的所有程序 注意外層是esc鍵下面那個頓號,內層是單引號 2.ps -ef |grep -v grep |grep

linux執行jar與關閉jar程序

指令碼如下: #埠號,根據埠號確定PID PORT=8081 #啟動命令所在目錄 HOME='/usr/etc/server' #查詢監聽PORT埠的程式,awk:過濾文字;cut-d / -f 1

Linux使用ps命令檢視某個程序檔案的啟動位置

[root@izbp190idbje1fp4hnpk53z src]# ps aux | grep redis [root@

如何理解Linux的動態庫概念和靜態庫概念通俗易懂的解釋如下:

動態庫和靜態庫都是一組函式集合,打包在一起供應用程式呼叫,區別是: 靜態庫名稱一般為xxx.a,在編譯時和應用程式連結在一起,這樣的應用程式佔用空間較大。 動態庫名稱一般為xxx.so,對於動態庫即可以在編譯時連結,也可以使用dlopen()/dlsy

Python學習【第20篇】:互斥鎖以及程序之間的三種通訊方式(IPC)以及生產者個消費者模型 python併發程式設計之多程序1-----------互斥鎖與程序間的通訊

python併發程式設計之多程序1-----------互斥鎖與程序間的通訊 一、互斥鎖 程序之間資料隔離,但是共享一套檔案系統,因而可以通過檔案來實現程序直接的通訊,

Linux程序虛擬地址空間

1.以32位系統為例,Linux系統中每個程序共有3GB的使用者地址空間,當用戶呼叫系統呼叫時,核心執行緒會代表程序執行,此時是在核心空間內執行的,故所有程序共享1GB的核心空間. 所以,總的來說,每個程序可用的地址空間共有4GB 2.程序的3GB使用者地址空