1. 程式人生 > >計算機基礎知識瞭解

計算機基礎知識瞭解

 linux檔案系統:
 先說一下格式化:每種作業系統所設定的檔案屬性/許可權並不相同,為了存放這些檔案所需的資料,因此就需要將分割槽格式化,以成為作業系統能夠利用的檔案系統格式。linux的檔案格式為Ext2/Ext3,現在好像已經到了Ext4.windows 作業系統為vfat或者NTFS。
linux檔案系統:
  作業系統的檔案資料除了檔案實際內容外,還有非常多的屬性,如檔案許可權(rwx)與檔案屬性(所有者、群組、時間引數等)。
  檔案系統通常將這兩部分資料存放在不同的塊。許可權屬性放到 inode 中,實際資料放到 data block 中。
  還有一個超級塊(super block)會記錄檔案系統的整體資訊,包括 inode 與block 的數量、使用量等。

  inode:記錄檔案屬性,一個檔案佔用一個inode,同時記錄此檔案的資料所在的block號碼;
  block:實際記錄檔案的內容,若檔案太大時會佔用多個 block ;
  super block:記錄檔案系統的整體資訊,包括inode/block 的總量、使用量、剩餘量,以及檔案系統的格式與相關資訊等。
 
每個inode與block都有編號,而每個檔案系統都會佔用一個inode,inode中有檔案資料放置的block號碼。我們可以找到檔案的inode,然後找出檔案所放置資料的block號碼,之後讀出資料。
這種資料訪問方式成為索引式檔案系統。這種檔案系統一般不太需要經常進行磁碟碎片整理。
而 U 盤等為FAT檔案格式,每個block號碼都記錄在前一個block號碼中,因此資料的讀取效能較差,用久了得進行碎片整理。

普通檔案的block塊儲存的是檔案內容,目錄的block塊則儲存了該目錄下所有檔案的inode號及對應的檔名等資訊。


虛擬記憶體:
    WINDOWS運用了虛擬記憶體技術,即拿出一部分硬碟空間來充當記憶體使用,這部分空間即稱為虛擬記憶體,虛擬記憶體在硬碟上的存在形式就是 PAGEFILE.SYS這個頁面檔案。

虛擬記憶體地址:
    什麼是虛擬記憶體地址和實體記憶體地址呢。假設你的計算機是32位,那麼它的地址匯流排是32位的,也就是它可以定址0~0xFFFFFFFF(4G)的地址空間,
但如果你的計算機只有256M的實體記憶體0x~0x0FFFFFFF(256M),同時你的程序產生了一個不在這256M地址空間中的地址,那麼計算機該如何處理呢?回答這個問題前,先說明計算機的記憶體分頁機制。
    計算機會對虛擬記憶體地址空間(32位為4G)分頁產生頁(page),對實體記憶體地址空間(假設256M)分頁產生頁幀(page frame),這個頁和頁幀的大小是一樣大的,
所以呢,在這裡,虛擬記憶體頁的個數勢必要大於實體記憶體頁幀的個數。在計算機上有一個頁表(page table),就是對映虛擬記憶體頁到實體記憶體頁的,更確切的說是頁號到頁幀號的對映,而且是一對一的對映。
但是問題來了,虛擬記憶體頁的個數 > 實體記憶體頁幀的個數,豈不是有些虛擬記憶體頁的地址永遠沒有對應的實體記憶體地址空間?不是的,作業系統是這樣處理的。作業系統有個頁面失效(page fault)功能。
作業系統找到一個最少使用的頁幀,讓他失效,並把它寫入磁碟,隨後把需要訪問的頁放到頁幀中,並修改頁表中的對映,這樣就保證所有的頁都有被排程的可能了。這就是處理虛擬記憶體地址到實體記憶體的步驟。

記憶體對映:
    虛擬記憶體的目標儲存器是磁碟,所以虛擬記憶體區域是和磁碟中的檔案對應的。初始化虛擬記憶體區域的內容時,會把虛擬記憶體區域和一個磁碟檔案物件對應起來,這個過程叫記憶體對映(memory mapping)
    由於記憶體對映機制,所以一個磁碟檔案物件可以被多個程序共享訪問,也可以被多個程序物件私有訪問。如果是共享訪問,那麼一個程序對這個物件的修改會顯示到其他程序。如果是私有訪問,
核心會採用寫時拷貝copy on write的方式,如果一個程序要修改一個私有的寫時拷貝的物件,會產生一個保護故障,核心會拷貝這個私有物件,寫程序會在新的私有物件上修改,
其他程序仍指向原來的私有物件。
理解了記憶體對映機制就可以理解幾個重要的函式:
    1. fork函式會建立帶有獨立虛擬地址空間的新程序,核心會為新程序建立各種資料結構,分配一個唯一的PID,把當前程序的mm_struct, area結構和頁表都複製給新程序。
兩個程序的共享同樣的區域,這些區域包括共享的記憶體對映和私有的記憶體對映。私有的記憶體對映區域都被標記為私有的寫時拷貝。如果新建的程序對這些虛擬頁做修改,
那麼會觸發寫時拷貝,為新的程序維護私有的虛擬地址空間。
    
    2. mmap函式可以建立新的虛擬記憶體area,並把磁碟物件對映到新建的area。
mmap可以用作高效的操作檔案的方式,直接把一個檔案對映到記憶體,通過修改記憶體就相當於修改了磁碟檔案,減少了普通檔案操作的一次拷貝操作。
普通檔案操作時會先把檔案內容從磁碟複製到核心空間管理的一塊虛擬記憶體區域area,然後核心再把內容複製到使用者空間管理的虛擬記憶體area。 
mmap相當於建立了一個核心空間和使用者空間共享的area,檔案的內容只需要在這個area對應的實體記憶體和磁碟檔案之間交換即可。


從檔案IO的角度來說,Linux把一切IO都抽象成了檔案,比如普通檔案IO,網路IO,統統都是檔案,利用open系統呼叫返回一個整數作為檔案描述符file descriptor,
程序可以利用file descriptor作為引數在任何系統呼叫中表示那個開啟的檔案。核心為程序維護了一個檔案描述符表來保持程序所有獲得的file descriptor。

作業系統利用fork系統呼叫來建立一個子程序。fork所建立的子程序會複製父程序的虛擬地址空間。
要理解“複製”和“共享”的區別,複製的意思是會真正在實體記憶體複製一份內容,會真正消耗新的實體記憶體。共享的意思是使用指標指向同一個地址,不會真正的消耗實體記憶體。
理解這兩個概念的區別很重要,這是程序和執行緒的根本區別之一。

程序間通訊:
兩個程序不能通過簡單的共享變數的方式來進行程序間通訊,也就是說程序不能通過直接共享記憶體的方式來進行程序間通訊,只能採用訊號,管道等方式來進行程序間通訊。這樣的效率肯定比直接共享記憶體的方式差

clone系統呼叫:
在Linux系統中,執行緒是使用clone系統呼叫,clone是一個輕量級的fork,它提供了一系列的引數來表示執行緒可以共享父類的哪些資源,比如頁表,開啟檔案表等等。我們上面說過了共享和複製的區別,共享只是簡單地用指標指向同一個實體地址,不會在父程序之外開闢新的實體記憶體。
clone系統呼叫可以指定建立的執行緒開始執行程式碼位置,也就是Java中的Thread類的run方法