趣談Linux作業系統 05 系統呼叫

2021-10-12 17:54:16 字數 2516 閱讀 3573

建立程序的系統呼叫叫fork。這個名字很奇怪,中文叫「分支」。為啥啟動乙個新程序叫「分支」呢?在 linux 裡,要建立乙個新的程序,需要乙個老的程序呼叫 fork 來實現,其中老的程序叫作父程序(parent process),新的程序叫作子程序(child process)。

當父程序呼叫 fork 建立程序的時候,子程序將各個子系統為父程序建立的資料結構也全部拷貝了乙份,甚至連程式**也是拷貝過來的。按理說,如果不進行特殊的處理,父程序和子程序都按相同的程式**進行下去,這樣就沒有意義了。所以,我們往往會這樣處理:對於 fork 系統呼叫的返回值,如果當前程序是子程序,就返回 0;如果當前程序是父程序,就返回子程序的程序號。這樣首先在返回值這裡就有了乙個區分,然後通過 if-else 語句判斷,如果是父程序,還接著做原來應該做的事情;如果是子程序,需要請求另乙個系統呼叫execve來執行另乙個程式,這個時候,子程序和父程序就徹底分道揚鑣了,也就產生了乙個分支(fork)了。

同樣是「先拷貝,再修改」的策略,你可能會問,新程序都是父程序 fork 出來的,那到底誰是第乙個呢?

對於作業系統也一樣,啟動的時候先建立乙個所有使用者程序的「祖宗程序」。這個在講系統啟動的時候還會詳細講,我這裡先不多說。有時候,父程序要關心子程序的運**況,這畢竟是自己身上掉下來的肉。有個系統呼叫waitpid,父程序可以呼叫它,將子程序的程序號作為引數傳給它,這樣父程序就知道子程序執行完了沒有,成功與否。所以說,所有子專案最終都是

對於程序的記憶體空間來講,放程式**的這部分,我們稱為**段(code segment)

對於程序的記憶體空間來講,放程序執行中產生資料的這部分,我們稱為資料段(data segment)。其中區域性變數的部分,在當前函式執行的時候起作用,當進入另乙個函式時,這個變數就釋放了;也有動態分配的,會較長時間儲存,指明才銷毀的,這部分稱為堆(heap)

乙個程序的記憶體空間是很大的,32 位的是 4g,64 位的就更大了。所以,程序自己不用的部分就不用管,只有程序要去使用部分記憶體的時候,才會使用記憶體管理的系統呼叫來登記,說自己馬上就要用了,希望分配一部分記憶體給它,但是這還不代表真的就對應到了物理記憶體。只有真的寫入資料的時候,發現沒有對應物理記憶體,才會觸發乙個中斷,現分配物理記憶體。這裡我們介紹兩個在堆裡面分配記憶體的系統呼叫,brk和mmap。當分配的記憶體數量比較小的時候,使用brk,會和原來的堆的資料連在一起,當分配的記憶體數量比較大的時候,使用mmap,會重新劃分一塊區域。

檔案管理其實花樣不多,拍著腦袋都能想出來,無非是建立、開啟、讀、寫等。對於檔案的操作,下面這六個系統呼叫是最重要的:對於已經有的檔案,可以使用open開啟這個檔案,close關閉這個檔案;對於沒有的檔案,可以使用creat建立檔案;開啟檔案以後,可以使用lseek跳到檔案的某個位置;可以對檔案的內容進行讀寫,讀的系統呼叫是read,寫是write。但是別忘了,linux 裡有乙個特點,那就是一切皆檔案。啟動乙個程序,需要乙個程式檔案,這是乙個二進位制檔案。啟動的時候,要載入一些配置檔案,例如ymlproperties等,這是文字檔案;啟動之後會列印一些日誌,如果寫到硬碟上,也是文字檔案。但是如果我想把日誌列印到互動控制台上,在命令列上唰唰地列印出來,這其實也是乙個檔案,是標準輸出 stdout 檔案。這個程序的輸出可以作為另乙個程序的輸入,這種方式稱為管道,管道也是乙個檔案。程序可以通過網路和其他程序進行通訊,建立的 socket,也是乙個檔案。程序需要訪問外部裝置,裝置也是乙個檔案。檔案都被儲存在資料夾裡面,其實資料夾也是乙個檔案。程序執行起來,要想看到程序執行的情況,會在/proc下面有對應的程序號,還是一系列檔案。

每個檔案,linux 都會分配乙個檔案描述符(file descriptor),這是乙個整數。有了這個檔案描述符,我們就可以使用系統呼叫,檢視或者干預程序執行的方方面面。所以說,檔案操作是貫穿始終的,這也是「一切皆檔案」的優勢,就是統一了操作的入口,提供了極大的便利。

glibc 是 linux 下使用的開源的標準 c 庫,它是 gnu 發布的 libc 庫。glibc 為程式設計師提供豐富的 api,除了例如字串處理、數**算等使用者態服務之外,最重要的是封裝了作業系統提供的系統服務,即系統呼叫的封裝。每個特定的系統呼叫對應了至少乙個 glibc 封裝的庫函式,比如說,系統提供的開啟檔案系統呼叫 sys_open 對應的是 glibc 中的 open 函式。有時候,glibc 乙個單獨的 api 可能呼叫多個系統呼叫,比如說,glibc 提供的 printf 函式就會呼叫如 sys_open、sys_mmap、sys_write、sys_close 等等系統呼叫。也有時候,多個 api 也可能只對應同乙個系統呼叫,如 glibc 下實現的 malloc、calloc、free 等函式用來分配和釋放記憶體,都利用了核心的 sys_brk 的系統呼叫。

作業系統概論 05

5 裝置管理 併發程序訪問共享資源的時候可以有兩種關係 競爭關係 協作關係 5.1外圍裝置的分配 1獨佔裝置與空閒裝置 獨佔裝置是指沒次只能讓乙個裝置獨佔 如輸入機 印表機等共享裝置是指允許幾個作業同時使用裝置 2裝置的絕對號和相對號 絕對號就是講每一台裝置確定乙個編號 相對號就是由使用者給出的裝置...

趣談Linux作業系統學習筆記 記憶體管理(22講)

記憶體管理資訊 task struct 的 mm struct 中 整個虛擬記憶體空間 1 是使用者態位址空間 2 是核心態位址空間 那這兩部分的分界線在 呢?這就要 task size 來定義 1 ifdef config x86 322 3 user space process size 3gb...

Linux作業系統

本書以當前最流行的red hat linux的最新發行版本為基礎,論述作業系統的基本原理 基本思想和基本方法,並在此基礎上介紹linux網路作業系統的核心結構 安裝 配置 基本操作 系統管理及網路應用等,從而系統 完整地講述linux作業系統從基本原理到應用實踐的主要內容。本書注意理論內容的選取,注...