主頁:醋溜馬桶圈-CSDN博客
專欄:Linux_醋溜馬桶圈的博客-CSDN博客
gitee:mnxcc (mnxcc) - Gitee.com
目錄
1.環(huán)境變量
1.1 基本概念
1.2 常見環(huán)境變量?
1.3 查看環(huán)境變量方法?
1.4?和環(huán)境變量相關(guān)的命令
1.5 環(huán)境變量的組織方式
1.6 通過代碼如何獲取環(huán)境變量
1.6.1 命令行第三個(gè)參數(shù)
1.6.2 通過第三方變量environ獲取
1.7 通過系統(tǒng)調(diào)用獲取或設(shè)置環(huán)境變量
1.8 環(huán)境變量通常是具有全局屬性的?
2.程序地址空間?
2.1 研究背景
2.2 程序地址空間回顧?
2.3 進(jìn)程地址空間
3.Linux2.6內(nèi)核進(jìn)程調(diào)度隊(duì)列
3.1 一個(gè)CPU擁有一個(gè)runqueue
3.2 優(yōu)先級(jí)?
3.3 活動(dòng)隊(duì)列?
3.4?過期隊(duì)列
3.5 active指針和expired指針
3.6 總結(jié)?
1.環(huán)境變量
1.1 基本概念
- 環(huán)境變量(environment variables)一般是指在操作系統(tǒng)中用來指定操作系統(tǒng)運(yùn)行環(huán)境的一些參數(shù)
- 如:我們?cè)诰帉慍/C++代碼的時(shí)候,在鏈接的時(shí)候,從來不知道我們的所鏈接的動(dòng)態(tài)靜態(tài)庫在哪里,但是照樣可以鏈接成功,生成可執(zhí)行程序,原因就是有相關(guān)環(huán)境變量幫助編譯器進(jìn)行查找。
- 環(huán)境變量通常具有某些特殊用途,還有在系統(tǒng)當(dāng)中通常具有全局特性
1.2 常見環(huán)境變量?
- PATH : 指定命令的搜索路徑
- HOME : 指定用戶的主工作目錄(即用戶登陸到Linux系統(tǒng)中時(shí),默認(rèn)的目錄)
- SHELL : 當(dāng)前Shell,它的值通常是/bin/bash
1.3 查看環(huán)境變量方法?
echo $NAME //NAME:你的環(huán)境變量名稱
1.4?和環(huán)境變量相關(guān)的命令
- echo: 顯示某個(gè)環(huán)境變量值
- export: 設(shè)置一個(gè)新的環(huán)境變量
- env: 顯示所有環(huán)境變量
- unset: 清除環(huán)境變量
- set: 顯示本地定義的shell變量和環(huán)境變量
1.5 環(huán)境變量的組織方式
每個(gè)程序都會(huì)收到一張環(huán)境表,環(huán)境表是一個(gè)字符指針數(shù)組,每個(gè)指針指向一個(gè)以’\0’結(jié)尾的環(huán)境字符串
1.6 通過代碼如何獲取環(huán)境變量
1.6.1 命令行第三個(gè)參數(shù)
#include <stdio.h>
int main(int argc, char* argv[], char* env[])
{
int i = 0;
for (; env[i]; i++) {
printf("%s\n", env[i]);
}
return 0;
}
1.6.2 通過第三方變量environ獲取
#include <stdio.h>
int main(int argc, char* argv[])
{
extern char** environ;
int i = 0;
for (; environ[i]; i++) {
printf("%s\n", environ[i]);
}
return 0;
}
libc中定義的全局變量environ指向環(huán)境變量表,environ沒有包含在任何頭文件中,所以在使用時(shí) 要用extern聲明
1.7 通過系統(tǒng)調(diào)用獲取或設(shè)置環(huán)境變量
- getnev
#include <stdio.h>
#include <stdlib.h>
int main()
{
printf("%s\n", getenv("PATH"));
return 0;
}
- 常用getenv和putenv函數(shù)來訪問特定的環(huán)境變量
1.8 環(huán)境變量通常是具有全局屬性的?
- 環(huán)境變量通常具有全局屬性,可以被子進(jìn)程繼承下去
#include <stdio.h>
#include <stdlib.h>
int main()
{
char* env = getenv("MYENV");
if (env) {
printf("%s\n", env);
}
return 0;
}
?
?直接查看,發(fā)現(xiàn)沒有結(jié)果,說明該環(huán)境變量根本不存在
- 導(dǎo)出環(huán)境變量
export MYENV="hello world"- 再次運(yùn)行程序,發(fā)現(xiàn)結(jié)果有了!說明:環(huán)境變量是可以被子進(jìn)程繼承下去的!
2.程序地址空間?
2.1 研究背景
- kernel 2.6.32
- 32位平臺(tái)
2.2 程序地址空間回顧?
在C語言的時(shí)候,有這樣的空間布局圖
可是我們對(duì)他并不理解
來段代碼感受一下?
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int g_val = 0;
int main()
{
pid_t id = fork();
if (id < 0) {
perror("fork");
return 0;
}
else if (id == 0) { //child
printf("child[%d]: %d : %p\n", getpid(), g_val, &g_val);
}
else { //parent
printf("parent[%d]: %d : %p\n", getpid(), g_val, &g_val);
}
sleep(1);
return 0;
}
輸出結(jié)果:
//與環(huán)境相關(guān),觀察現(xiàn)象即可
parent[2995]: 0 : 0x80497d8
child[2996] : 0 : 0x80497d8
我們發(fā)現(xiàn),輸出出來的變量值和地址是一模一樣的,很好理解呀,因?yàn)樽舆M(jìn)程按照父進(jìn)程為模版,父子并沒有對(duì)變量進(jìn)行進(jìn)行任何修改??墒菍⒋a稍加改動(dòng):
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int g_val = 0;
int main()
{
pid_t id = fork();
if (id < 0) {
perror("fork");
return 0;
}
else if (id == 0) { //child,子進(jìn)程肯定先跑完,也就是子進(jìn)程先修改,完成之后,父進(jìn)程再讀取
g_val = 100;
printf("child[%d]: %d : %p\n", getpid(), g_val, &g_val);
}
else { //parent
sleep(3);
printf("parent[%d]: %d : %p\n", getpid(), g_val, &g_val);
}
sleep(1);
return 0;
}
輸出結(jié)果:
//與環(huán)境相關(guān),觀察現(xiàn)象即可
child[3046]: 100 : 0x80497e8
parent[3045] : 0 : 0x80497e8比
我們發(fā)現(xiàn),父子進(jìn)程,輸出地址是一致的,但是變量內(nèi)容不一樣!能得出如下結(jié)論:
- 變量內(nèi)容不一樣,所以父子進(jìn)程輸出的變量絕對(duì)不是同一個(gè)變量
- 但地址值是一樣的,說明,該地址絕對(duì)不是物理地址!
- 在Linux地址下,這種地址叫做 虛擬地址
- 我們?cè)谟肅/C++語言所看到的地址,全部都是虛擬地址!物理地址,用戶一概看不到,由OS統(tǒng)一管理
OS必須負(fù)責(zé)將 虛擬地址 轉(zhuǎn)化成 物理地址?
2.3 進(jìn)程地址空間
所以之前說‘程序的地址空間’是不準(zhǔn)確的,準(zhǔn)確的應(yīng)該說成 進(jìn)程地址空間

說明:
上面的圖就足矣說名問題,同一個(gè)變量,地址相同,其實(shí)是虛擬地址相同,內(nèi)容不同其實(shí)是被映射到了不同的物理地址!
3.Linux2.6內(nèi)核進(jìn)程調(diào)度隊(duì)列
上圖是Linux2.6內(nèi)核中進(jìn)程隊(duì)列的數(shù)據(jù)結(jié)構(gòu)文章來源:http://www.zghlxwxcb.cn/news/detail-852129.html
3.1 一個(gè)CPU擁有一個(gè)runqueue
- ?如果有多個(gè)CPU就要考慮進(jìn)程個(gè)數(shù)的負(fù)載均衡問題?
3.2 優(yōu)先級(jí)?
- 普通優(yōu)先級(jí):100~139(我們都是普通的優(yōu)先級(jí),想想nice值的取值范圍,可與之對(duì)應(yīng)?。?
- 實(shí)時(shí)優(yōu)先級(jí):0~99(不關(guān)心)
3.3 活動(dòng)隊(duì)列?
- 時(shí)間片還沒有結(jié)束的所有進(jìn)程都按照優(yōu)先級(jí)放在該隊(duì)列
- nr_active: 總共有多少個(gè)運(yùn)行狀態(tài)的進(jìn)程
- queue[140]: 一個(gè)元素就是一個(gè)進(jìn)程隊(duì)列,相同優(yōu)先級(jí)的進(jìn)程按照FIFO規(guī)則進(jìn)行排隊(duì)調(diào)度,所以,數(shù)組下標(biāo)就是優(yōu)先級(jí)!
從該結(jié)構(gòu)中,選擇一個(gè)最合適的進(jìn)程,過程是怎么的呢??文章來源地址http://www.zghlxwxcb.cn/news/detail-852129.html
- 從0下表開始遍歷queue[140]
- 找到第一個(gè)非空隊(duì)列,該隊(duì)列必定為優(yōu)先級(jí)最高的隊(duì)列
- 拿到選中隊(duì)列的第一個(gè)進(jìn)程,開始運(yùn)行,調(diào)度完成!
- 遍歷queue[140]時(shí)間復(fù)雜度是常數(shù)!但還是太低效了!
- bitmap[5]:一共140個(gè)優(yōu)先級(jí),一共140個(gè)進(jìn)程隊(duì)列,為了提高查找非空隊(duì)列的效率,就可以用5*32個(gè)比特位表示隊(duì)列是否為空,這樣,便可以大大提高查找效率
3.4?過期隊(duì)列
- 過期隊(duì)列和活動(dòng)隊(duì)列結(jié)構(gòu)一模一樣
- 過期隊(duì)列上放置的進(jìn)程,都是時(shí)間片耗盡的進(jìn)程
- 當(dāng)活動(dòng)隊(duì)列上的進(jìn)程都被處理完畢之后,對(duì)過期隊(duì)列的進(jìn)程進(jìn)行時(shí)間片重新計(jì)算
3.5 active指針和expired指針
- active指針永遠(yuǎn)指向活動(dòng)隊(duì)列
- expired指針永遠(yuǎn)指向過期隊(duì)列
- 可是活動(dòng)隊(duì)列上的進(jìn)程會(huì)越來越少,過期隊(duì)列上的進(jìn)程會(huì)越來越多,因?yàn)檫M(jìn)程時(shí)間片到期時(shí)一直都存在的
- 沒關(guān)系,在合適的時(shí)候,只要能夠交換active指針和expired指針的內(nèi)容,就相當(dāng)于有具有了一批新的活動(dòng)進(jìn)程!
3.6 總結(jié)?
- 在系統(tǒng)當(dāng)中查找一個(gè)最合適調(diào)度的進(jìn)程的時(shí)間復(fù)雜度是一個(gè)常數(shù),不隨著進(jìn)程增多而導(dǎo)致時(shí)間成本增加,我們稱之為進(jìn)程調(diào)度O(1)算法?
到了這里,關(guān)于【Linux】進(jìn)程>環(huán)境變量&&地址空間&&進(jìn)程調(diào)度的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!