一、進程優(yōu)先級
1、基本概念
cpu 資源分配的先后順序,就是指進程的優(yōu)先權(priority) .優(yōu)先權高的進程有優(yōu)先執(zhí)行權利。配置進程優(yōu)先權對多任務環(huán)境的 Linux 很有用,可以改善系統(tǒng)性能。 還可以把進程運行到指定的 CPU 上,這樣一來,把不重要的進程安排到某個 CPU,可以大大改善系統(tǒng)整體性能。
2、查看以及修改系統(tǒng)進程的優(yōu)先級
在 Linux 或者 unix 系統(tǒng)中,用ps –al命令則會類似輸出以下幾個內容, 其中:
UID : 代表執(zhí)行者的身份
PID : 代表這個進程的代號
PPID :代表這個進程是由哪個進程發(fā)展衍生而來的,亦即父進程的代號
PRI :代表這個進程可被執(zhí)行的優(yōu)先級,其值越小越早被執(zhí)行
NI :代表這個進程的 nice 值,其表示進程可被執(zhí)行的優(yōu)先級的修正數(shù)值。
我們看到我們現(xiàn)在有兩個進程 bash ps 它們的進程優(yōu)先級都是 80,如果我們要修改它們的優(yōu)先級就要用到 NI 的 nice 值了。
?
P?R?I?(?n?e?w?)?=?P?R?I?(?o?l?d?)?+?n?i?c?e?PRI(new)=PRI(old)+nicePRI(new)=PRI(old)+nice
?
從這個公式中我們知道 新的 PRI = 老的 PRI + nice 值,但是這個老的 PRI 的值是指 PRI 最初的默認值,例如上面的bash ps 是 80,那么這個 PRI 以后不論怎么改老的 PRI 都是 80,當然大多數(shù)進程默認的 PRI 都是 80。
此外 nice 是有范圍的!其取值范圍是 - 20 至 19,一共 40 個級別。
于是下面我們去嘗試去更改processC進程的優(yōu)先級。
注意:將進程優(yōu)先級調高(即將 nice 值設置為負數(shù))需要 root 用戶進行操作!
修改進程優(yōu)先級的 Linux 指令
top命令
進入top后按 "r" -> 輸入進程 PID -> 輸入 nice 值
按下 “r”
輸入 -20
再次[查看進程]的相關信息:
我們發(fā)現(xiàn)進程的優(yōu)先級確實改變了,但是我們能改變進程優(yōu)先級有限[ ? 20 , 19 ] [-20,19][?20,19],因為調度器不允許我們將一個進程設置的優(yōu)先級太高,進而導致其他進程難以被調度。
3、一些其他的關于進程優(yōu)先級的指令和函數(shù)調用
nice指令,nice 命令的功能是用于調整進程的優(yōu)先級,合理分配系統(tǒng)資源。-n 參數(shù)是 nice 值的優(yōu)先級別,
以 nice 值為 -5 的方式執(zhí)行指定程序
查看進程優(yōu)先級
renice命令可以修改正在運行的進程的調度優(yōu)先級。
renice更改一個或多個進程的調度優(yōu)先級。第一個參數(shù)是要使用的優(yōu)先級值,另一個參數(shù)被表示為進程標識信息。
?
renice?[-n]?priority?[-gpu]?identifier
?
-g, 后面加組的 pgid, 改變一個組的進程優(yōu)先級
-u, 后面加 user name 或 uid,改變一個用戶所擁有的進程優(yōu)先級。
-p, 后面加 pid ,改變一個進程的進程優(yōu)先級。
使用renice命令
函數(shù)調用
在 Linux 中關于改變進程優(yōu)先級函數(shù)調用主要有兩個:getpriority() 與setpriority()。
4、與進程優(yōu)先級有關的一些進程性質
競爭性: 系統(tǒng)進程數(shù)目眾多,而 CPU 資源只有少量,甚至 1 個,所以進程之間是具有競爭屬性的。為了高效完成任務,更合理競爭相關資源,便具有了優(yōu)先級
獨立性: 多進程運行,需要獨享各種資源,多進程運行期間互不干擾。
并行: 多個進程在多個 CPU 下,分別同時進行運行,這稱之為并行
并發(fā): 多個進程在一個 CPU 下采用進程切換的方式,在一段時間之內,讓多個進程都得以推進,稱之為并發(fā)
二、環(huán)境變量
1、基本概念
環(huán)境變量 (environment variables) 一般是指在操作系統(tǒng)中用來指定操作系統(tǒng)運行環(huán)境的一些參數(shù),環(huán)境變量通常具有某些特殊用途,在系統(tǒng)當中通常具有全局特性。
如:我們在編寫 C/C++ 代碼的時候,在鏈接的時候,從來不知道我們的所鏈接的動態(tài)[靜態(tài)庫]在哪里,但是照樣可以鏈接成功,生成可執(zhí)行程序,原因就是有相關環(huán)境變量幫助編譯器進行查找。
2、和環(huán)境變量相關的命令
1.env: 顯示所有環(huán)境變量
2.echo: 顯示的變量值 (需要帶上 $ 符號)
3.export: 設置一個新的環(huán)境變量,或者將本地[變量提升]成環(huán)境變量。
4.unset: 清除環(huán)境變量
5.set: 顯示本地定義的 shell 變量和環(huán)境變量
3、Linux 中的常見環(huán)境變量介紹
PATH : 指定命令的搜索路徑
例如我們使用的 Linux 中 ls pwd命令,其實就是一個個 C 語言寫的一個個小程序,為什么我們運行自己寫的程序就要用./ + 自己的程序名 ,而我們運行l(wèi)s pwd 從來不加./,這就和環(huán)境變量 PATH 有關了!
我們查看環(huán)境變量可以使用echo $環(huán)境變量命令:
默認情況下我們使用的 Linux 指令會去 PATH 路徑下尋找源程序,由于ls指令的路徑位置就在 PATH 的環(huán)境變量中所以我們可以不用加./
我們現(xiàn)在嘗試將我們的路徑添加到 PATH 環(huán)境變量里面,來讓我們的程序也不需要加./,這時我們就需要使用一個新的指令了:export
export令可以將本地變量提升成環(huán)境變量,于是我們將我們的路徑添加到 PATH 中就可以這樣寫:
?
export?PATH=$PATH:你要添加的路徑
?
當然我們使用export命令是暫時將本地變量提升為環(huán)境變量,當我們退出云服務器或關機重啟都會消除export暫時提升的環(huán)境變量,想要真正的修改我們要修改相應的配置文件。
當然我們還可以將我們寫的程序拷貝到 Linux 的 PATH 默認路徑下,這樣我們也不用使用./了,在 Linux 中,把可執(zhí)行程序,拷貝到系統(tǒng)默認路徑下,讓我們可以直接訪問的方式,相當于 Linux 下軟件的安裝!
HOME : 指定用戶的主工作目錄 (即用戶登陸到 Linux 系統(tǒng)中時, 默認的目錄)
由于 HOME 環(huán)境變量的存在,我們使用相同的命令cd ~卻得到了不同的結果。
SHELL : 當前 Shell, 它的值通常是 / bin/bash。
4、環(huán)境變量的組織方式以及在 C 代碼中如何獲取環(huán)境變量
在 Shell 內部,環(huán)境變量其實是以環(huán)境變量表的方式進行維護的!
此外環(huán)境變量還具有全局性,我們知道我們在 bash 下運行的程序其父進程都是 bash, 那么 bash 就可以將自己的環(huán)境變量傳遞給子進程,并在子進程中發(fā)揮作用!
我們來看一段代碼來驗證環(huán)境變量具有全局性。
1. C 庫函數(shù)getenv()獲得單個環(huán)境變量
在看驗證代碼之前我們先了解一個函數(shù)getenv() getenv()是一個 C 庫函數(shù), 它可以獲取一個環(huán)境變量的內容
函數(shù)原型:
函數(shù)的參數(shù)是環(huán)境變量的名稱,返回值是一個char*字符串記錄了環(huán)境變量里面的內容, 如果調用失敗會返回 NULL 指針。
實例代碼
?
#include???? #include ??? int?main() { ????char*?env?=??getenv("USER");//USER是環(huán)境變量 ????if(env?==?NULL) ????{ ????????perror("getenv?fail:"); ????} ????printf("%s ",env); ????return?0; }
?
代碼輸出結果
我們在代碼里面多出來的USER變量就是來自 Shell 傳遞給我們的test1c進程的環(huán)境變量!
2. main()函數(shù)參數(shù)獲得環(huán)境變量
此外我們我們還可以用main函數(shù)的參數(shù)來獲得所有環(huán)境變量的地址,通過地址我們也能遍歷所有環(huán)境變量
函數(shù)原型
?
int?main(int?argc,?char?*argv[],?char?*envp[]);
?
在這里我們先不談論函數(shù)的參數(shù) argc *argv[], 我們來談論第三個參數(shù)!其中*envp[]是一個字符數(shù)組指針,指向的是一個指針數(shù)組,數(shù)組名代表首元素的地址,首元素是一個字符指針,*envp[]剛好又是指向首元素的指針,故其實*envp[]其實是一個二級指針!
明白了這些,我們來看下面一段代碼:
?
#includeint?main(int?argc,?int?*argv[],?int?*envp[]) { ????for(int?i?=0;?envp[i]?!=?NULL?;?++i) ????{ ???????//打印所有環(huán)境變量,相當于 env 命令! ????????printf("envp[%d]-->%s ",?i,?envp[i]); ????} ????return?0; }
?
可以看到我們確實打印出了所有的環(huán)境變量,而且這個環(huán)境變量來自于其父進程 bash。
3. C 語言全局變量environ獲得環(huán)境變量
變量詳情:
environ變量是一個二級指針與main()函數(shù)參數(shù)的char *envp[]類似。遍歷所有環(huán)境變量也可以這樣寫:
?
#include???????? #include ??????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????int?main() { ????extern?char**?environ; ????for(int?i?=0;?environ[i]?!=?NULL;?++i) ????{ ????????printf("environ[%d]-->%s ",?i,?environ[i]); ????} ????return?0; }
?
5、不同用戶的環(huán)境變量是怎么形成的
通過上面的講解我們知道了環(huán)境變量的概念與作用,環(huán)境變量中的每一個,都有自己的用途: 有的是進行路徑查找的,有的時進行身份認證的,有的時進行動態(tài)庫查找的,有的是用來進行確認當前路徑等等每一個環(huán)境變量都有自己的特定應用場景。
我們也知道為什么,對于不同的用戶其環(huán)境變量也并不相同,例如我們上面的 root 用戶的環(huán)境變量與 pan 的環(huán)境變量有的一樣有的不一樣,那么 Linux 是怎樣形成不同的環(huán)境變量的呢?
這里先給出結論:環(huán)境變量本質就是一個內存級的一張表,這張表由用戶在登陸會統(tǒng)的時候,給特定用戶形成屬于自己的環(huán)境變量表。
在我們的家目錄下有兩個文件叫 .bashrc .bash_profile 在根目錄下有一個bashrc的文件
打開這些文件看看!
6、main() 函數(shù)的命令行參數(shù)
在前面我們談論中我們說到過main()函數(shù)的參數(shù)問題,我們還有兩個參數(shù)沒有談論int argc char *argv[]。現(xiàn)在我們來討論它們!
由于 C 語言中無法傳遞整個數(shù)組,所以在函數(shù)中想要獲得數(shù)組元素的個數(shù)必須在傳參時就要提前傳遞好,于是其中int argc 就是char *argv[]數(shù)組指針指向的數(shù)組的有效元素個數(shù),不包含 NULL。
這個char *argv[]是一個數(shù)組指針,其指向的數(shù)組里面存放的都是char *的指針,這些char *的指針指向的內容需要我們使用命令行的方式進行設置。
我們先看下面一段代碼:
?
#include???? int?main(int?argc,?int?*argv[]) { ?????printf("argc?=?%d ",argc); ?????for(int?i?=?0;?argv[i]?!=?NULL;?++i) ????{ ????????printf("argv[%d]-->%s ",?i,?argv[i]); ????} ????return?0; }
?
運行結果:
我們 Linux 中l(wèi)s命令有許多參數(shù)如-a -l -d -n,ls本質上就是 C 語言寫的一個程序,它為什么能根據(jù)不同的參數(shù)執(zhí)行不同的功能就是因為使用了 mian() 函數(shù)的命令行參數(shù)!
審核編輯:湯梓紅
評論
查看更多