文章目錄
- Linux優先級
- Linux的調度與切換
- **進程切換**:
- **進程調度**:
- 優先級
- 活動隊列
- 過期隊列
- active指針和expired指針
- 環境變量
- main函數參數 `int main(int argc, char *argv[], char *envp[]) `
- 環境變量
- 環境變量和本地變量
- `echo`查看單個環境變量的方法
- `export`添加路徑到環境變量PATH
- `export`設置環境變量
- `set`和`export`設置環境變量
- `set`顯示本地定義的shell變量和環境變量
- `env`顯示環境變量
- `unset`刪除環境變量或本地變量
- 環境變量的組織方式
- 通過代碼如何獲取環境變量
- 1. 命令行第三個參數(`main`函數第三個參數)
- 2. 通過第三方變量`environ`獲取
- 3. `getenv()`獲取指定名稱的環境變量的值
- 環境變量通常是具有全局屬性的
- `bash_profile`文件
- 先有命令參數表,再有環境變量表
- 先有命令參數表,再有環境變量表
Linux優先級
Linux默認優先級是80. Linux的優先級是可以被修改的,Linux可被修改的優先級的范圍是**[60,99],因為nice的值為[-20,19]** 數字越小,優先級越高
Linux系統允許用戶調整優先級,但是不是直接修改pri,而是修改nice值。 pri=pri(old)+nice
修改進程優先級方法:輸入top->輸入r->輸入pid->輸入nice的改變值
Linux為什么調整優先級是要受限制的?
? 如果不加限制,將自己進程的優先級調整的非常高,別人的進程可以調整的非常低。優先級較高的進程,優先得到資源,后續還有源源不斷地進程產生,常規進程很難享受到CPU資源,會產生進程饑餓問題。
Linux的調度與切換
進程切換:
進程在運行的過程中,要產生大量的臨時數據,放在CPU的寄存器中!CPU內部的所有的臨時數據,我們叫做進程的硬件上下文。
進程下CPU時我們的進程進行保存硬件上下文,以保護上下文。
當進程在第二次被調度的時候,進程被放到CPU上開始運行,將曾經保存的硬件上下文進行恢復。
雖然寄存器數據放在了一個共享的CPU設備里面,但是所有的數據其實都是被進程私有的。
進程調度:
O(1)調度算法
Linux2.6內核中進程隊列的數據結構:
?
? 一個CPU擁有一個runqueue,一個runqueue有多個優先級隊列
優先級
-
普通優先級:100~139(我們都是普通的優先級,[60 ~ 99] ,nice的取值范圍 [-20~19] 是與之相對應的,映射)
-
實時優先級:0~99
活動隊列
-
時間片還沒結束的所有進程都按照優先級放在該隊列
-
nr_active:總共有多少個運行狀態的進程
-
queue[140]:一個元素就是一個進程隊列,相同優先級的進程按照FIFO規則進行排隊調度,所以數組下標就是優先級
-
從該結構中,選擇一個最合適的進程,過程是怎么的呢?
-
從0下表開始遍歷queue[140]
-
找到第一個非空隊列,該隊列必定為優先級最高的隊列
-
拿到選中隊列的第一個進程,開始運行,調度完成!
-
遍歷queue[140]時間復雜度是常數!但還是太低效了!
-
-
bitmap[5]:一共140個優先級,一共140個進程隊列,為了提高查找非空隊列的效率,就可以用5*32個 比特位表示隊列是否為空,這樣,便可以大大提高查找效率!
過期隊列
- 過期隊列和活動隊列結構一模一樣
- 過期隊列上放置的進程,都是時間片耗盡的進程或新來的進程
- 當活動隊列上的進程都被處理完畢之后,對過期隊列的進程進行時間片重新計算
active指針和expired指針
- active指針永遠指向活動隊列
- expired指針永遠指向過期隊列
- 可是活動隊列上的進程會越來越少,過期隊列上的進程會越來越多,因為進程時間片到期時一直都存在的。
- 但是在合適的時候,只要交換active指針和expired指針的內容,就相當于具有了一批新的活動進程
環境變量
main函數參數 int main(int argc, char *argv[], char *envp[])
argc
和 argv[]
、envp[]
是 C 語言中 main()
函數的參數,用于處理命令行參數。
argc
是一個整數,表示命令行參數的數量,包括程序名稱本身。它至少為 1,因為第一個參數始終是程序的名稱(通常是可執行文件的路徑)。argv
是一個指向字符指針數組的指針,它包含了命令行參數的實際內容。argv[0]
存儲的是程序的名稱,argv[1]
到argv[argc-1]
存儲的是命令行中給定的參數。envp
是一個指向字符指針數組的指針,其中每個元素都是一個指向環境變量字符串的指針。每個環境變量的格式是name=value
,例如PATH=/usr/bin
。這個參數通常用于訪問程序的環境變量。這些環境變量通常由操作系統傳遞給程序,用于提供關于運行環境的信息。
下面是一個簡單的示例,演示如何使用 argc
和 argv[]
處理命令行參數:
cCopy code解釋#include <stdio.h>int main(int argc, char *argv[]) {int i;// 打印程序名稱printf("Program name: %s\n", argv[0]);// 打印命令行參數printf("Number of arguments: %d\n", argc - 1);for (i = 1; i < argc; i++) {printf("Argument %d: %s\n", i, argv[i]);}return 0;
}
假設你將上述程序保存為 command_line.c
,然后編譯并運行它。當你在命令行中執行該程序時,可以給它傳遞一些參數。例如:
./command_line arg1 arg2 arg3
在這個例子中,程序會輸出以下內容:
Program name: ./command_line
Number of arguments: 3
Argument 1: arg1
Argument 2: arg2
Argument 3: arg3
這里,argc
的值是 4,因為有 4 個參數(包括程序名稱),而argv[]
包含了這些參數的實際值。
環境變量
環境變量是操作系統中用來存儲系統配置信息和進程運行環境的一種機制。在大多數操作系統中,包括Unix/Linux和Windows,環境變量都是以鍵值對的形式存在的。
一些基本概念包括:
- 環境變量名稱:每個環境變量都有一個名稱,用于唯一標識該變量。例如,"PATH"是一個常見的環境變量名稱,用于指定可執行程序的搜索路徑。
- 環境變量的取值:與每個環境變量名稱關聯的是一個取值,表示該變量當前的設置值。例如,"PATH"環境變量的取值可能是一串以冒號分隔的路徑列表。
- 設置環境變量:可以通過操作系統提供的工具或命令來設置環境變量。在Unix/Linux系統中,可以使用
export
命令;在Windows系統中,可以使用set
命令。 - 使用和獲取環境變量:程序可以通過讀取環境變量來獲取系統配置信息或自定義設置。程序可以通過環境變量接口讀取已經設置的環境變量。在C語言中,可以使用
getenv()
函數來獲取特定環境變量的取值。 - 常見環境變量:一些常見的環境變量包括PATH(指定可執行程序的搜索路徑)、HOME(當前用戶的主目錄路徑)、USER(當前用戶名)、PWD(指向當前工作目錄的路徑)等。
環境變量在操作系統中起著重要的作用,可以提供靈活的配置和運行環境設置,方便程序之間共享信息和系統管理。
環境變量和本地變量
環境變量和本地變量是計算機科學中兩個重要的概念,它們在編程和系統管理中起著不同的作用。
-
環境變量(Environment Variables):
- 環境變量是在操作系統級別定義的一種變量,可被所有在該操作系統上運行的程序所訪問。
- 環境變量通常包含了一些系統范圍內的配置信息,例如路徑、語言偏好、臨時文件夾等。
- 環境變量在操作系統啟動時被加載,并且可以在系統的整個生命周期內保持不變,除非被顯式修改。
- 在大多數操作系統中,可以通過命令行工具或配置文件來設置和管理環境變量。
-
本地變量(Local Variables):
- 本地變量是在程序或函數內部定義的變量,只在定義它們的作用域內可見和可訪問。
- 本地變量的作用域通常由它們所在的代碼塊(例如函數、循環、條件語句等)決定。
- 當程序執行離開該變量所在的作用域時,本地變量通常會被銷毀,釋放所占用的內存空間。
- 本地變量通常用于存儲臨時數據、函數參數以及在函數內部進行計算等臨時性任務。
雖然環境變量和本地變量在概念上有所不同,但它們都是在程序執行過程中用來存儲和操作數據的方式。在編程中,理解并正確使用這兩種變量類型是非常重要的。
echo
查看單個環境變量的方法
echo $NAME
//NAME:你的環境變量名稱
例如:echo $PATH
echo $PATH
是一條在 Unix/Linux 系統中查看環境變量 PATH
的命令。在 Unix/Linux 系統中,$PATH
是一個特殊的環境變量,用于指定系統在哪些目錄中搜索可執行文件。
當您在終端中執行 echo $PATH
時,系統會將 $PATH
替換為實際的環境變量值,并將其輸出到終端上。這個值通常是一系列由冒號分隔的目錄路徑。示例輸出可能如下所示:
/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/liuxu/.local/bin:/home/liuxu/bin
這表示系統會按照列出的順序依次搜索這些目錄,以查找用戶輸入的命令對應的可執行文件。
export
添加路徑到環境變量PATH
export PATH=/new/path/to/add:$PATH
注意 $PATH
表示當前 PATH
的值,這樣可以確保您添加的路徑位于現有路徑之前,這樣新的路徑會優先于之前的路徑進行搜索。
export
設置環境變量
在 Linux 中,export
是一個命令用于將變量聲明為環境變量,使得該變量對當前 shell 進程及其子進程可見。export
命令通常用于設置全局的環境變量。以下是 export
命令的基本用法:
將變量導出為環境變量:
如果要將一個變量聲明為環境變量,可以使用 export
命令。例如,假設有一個名為 MY_VARIABLE
的變量,要將其設置為環境變量,可以執行以下命令:
export MY_VARIABLE=value
這個命令將 MY_VARIABLE
設置為 value
并將其導出為環境變量,使得它對當前 shell 進程及其子進程可見。
set
和export
設置環境變量
在Linux中,set variable_name=value
和export variable_name=value
都是用來設置環境變量的方法,但它們之間存在一些區別:
-
set variable_name=value
:- 這種形式的設置僅在當前shell中有效,不會將變量傳遞給后續的子shell。
- 變量只在當前shell中可見,對于子shell或其他進程來說是不可見的。
-
export variable_name=value
:- 使用
export
命令設置的變量會被導出到當前shell及其所有后續的子shell。 - 這意味著子shell及其衍生進程(例如通過當前shell啟動的腳本)都能夠訪問和使用這些變量。
- 通過
export
導出的變量在當前shell退出后仍然有效,直到顯示地使用unset
命令將其刪除或重新設置。
- 使用
例如,假設你想設置一個環境變量MY_VAR
為hello
,然后在子shell中運行一個腳本。下面是兩種方法的對比:
使用set
命令:
set MY_VAR=hello
./my_script.sh
在my_script.sh
中,$MY_VAR
可能是未定義的,因為set
設置的變量不會自動傳遞給子shell。
使用export
命令:
export MY_VAR=hello
./my_script.sh
在my_script.sh
中,$MY_VAR
將會是hello
,因為export
命令導出的變量會傳遞給子shell。
set
顯示本地定義的shell變量和環境變量
set
env
顯示環境變量
在Linux中,env
是一個命令行實用程序,用于顯示當前環境中已設置的所有環境變量,或者在指定環境下執行給定的命令。
顯示當前環境變量:
如果不帶任何參數運行 env
命令,則會顯示當前 shell 進程中的所有環境變量及其值。示例:
env
這個命令會列出當前 shell 進程中定義的所有環境變量及其值。
unset
刪除環境變量或本地變量
在 Linux 命令行環境中,可以使用 unset
命令來刪除一個或多個環境變量。unset
命令會將指定的變量從當前 shell 進程中移除,使得它在當前 shell 及其子進程中不再可用。
unset VAR_NAME
這個命令會從當前 shell 進程中移除名為 VAR_NAME
的環境變量。如果要刪除多個環境變量,可以將它們依次列出,用空格分隔。
環境變量的組織方式
每個程序都會收到一張環境表,環境表是一個字符指針數組,每個指針指向一個以’\0’結尾的環境字符串
通過代碼如何獲取環境變量
1. 命令行第三個參數(main
函數第三個參數)
#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;
}
2. 通過第三方變量environ
獲取
#include <stdio.h>
#include <stdlib.h>// 聲明全局變量 environ,存儲環境變量
extern char **environ;// 主函數,接受命令行參數 argc 和 argv
int main(int argc, char *argv[]) {// 創建指向環境變量字符串數組的指針char **env = environ;// 打印環境變量信息的標題printf("Environment variables:\n");// 遍歷環境變量數組,并打印每個環境變量while (*env != NULL) {printf("%s\n", *env);env++;}return 0;
}
//定義的全局變量environ指向環境變量表,environ沒有包含在任何頭文件中,所以在使用時 要用extern聲明。
3. getenv()
獲取指定名稱的環境變量的值
getenv() 是 C 標準庫中的一個函數,用于從環境中獲取指定名稱的環境變量的值。
它的聲明和用法如下:
聲明:
char* getenv(const char* name);
參數:
- name: 要獲取值的環境變量名稱。
返回值:
- 如果環境變量存在,返回一個指向其值的指針。
- 如果環境變量不存在,返回
NULL
。
例子:
#include <stdio.h>
#include <stdlib.h>int main() {char* path = getenv("PATH");if (path != NULL) {printf("PATH is %s\n", path); } else {printf("PATH not set\n");}return 0;
}
獲取并打印 PATH
環境變量的值。
使用 getenv()
函數可以在 C 程序中方便地獲取系統環境變量,用于程序運行的配置和決策等。它允許程序動態獲取運行時環境的信息。
環境變量通常是具有全局屬性的
環境變量通常具有全局屬性,可以被子進程繼承下去
bash_profile
文件
在Linux中,bash_profile
是一個特殊的配置文件,它用于配置 Bash shell 的環境和行為。每當用戶登錄到系統時,Bash shell 將會執行 bash_profile
文件中的命令和設置。
下面是關于 bash_profile
文件的一些重要信息:
-
作用:
bash_profile
文件用于配置用戶的個性化環境,例如設置環境變量、定義別名、執行特定命令等。- 它是用戶級別的配置文件,每個用戶都可以在自己的主目錄中創建一個
bash_profile
文件來定制自己的 Shell 環境。
-
位置:
bash_profile
文件通常位于用戶的主目錄下,文件名為.bash_profile
。- 用戶登錄時,Bash shell 會自動查找并執行該文件。如果不存在,則會嘗試執行其他類似的文件,比如
.bash_login
或.profile
。
-
內容:
bash_profile
文件可以包含各種 Bash 命令和設置,例如:- 設置環境變量(如
PATH
、PS1
等)。 - 定義別名和函數。
- 運行特定的腳本或程序。
- 進行系統初始化和配置等。
- 設置環境變量(如
-
編輯:
- 用戶可以使用文本編輯器(如
vi
、nano
、gedit
等)編輯.bash_profile
文件。 - 修改完成后,需要保存并關閉編輯器,更改將在下次用戶登錄時生效。
- 用戶可以使用文本編輯器(如
-
加載:
- 當用戶登錄時,Bash shell 會自動執行
.bash_profile
文件中的命令和設置。 - 如果用戶需要立即使更改生效,可以使用
source
命令重新加載.bash_profile
,例如:source ~/.bash_profile
。
- 當用戶登錄時,Bash shell 會自動執行
總之,bash_profile
文件是在 Linux 系統中用于配置用戶個性化環境的重要文件之一,它允許用戶定義各種環境變量、別名、函數以及其他個性化設置,以滿足其特定需求。
先有命令參數表,再有環境變量表
命令參數表通常會先有,然后在命令執行時,該命令會使用當前環境中的環境變量。
nano
、gedit
等)編輯 .bash_profile
文件。
- 修改完成后,需要保存并關閉編輯器,更改將在下次用戶登錄時生效。
- 加載:
- 當用戶登錄時,Bash shell 會自動執行
.bash_profile
文件中的命令和設置。 - 如果用戶需要立即使更改生效,可以使用
source
命令重新加載.bash_profile
,例如:source ~/.bash_profile
。
- 當用戶登錄時,Bash shell 會自動執行
總之,bash_profile
文件是在 Linux 系統中用于配置用戶個性化環境的重要文件之一,它允許用戶定義各種環境變量、別名、函數以及其他個性化設置,以滿足其特定需求。
先有命令參數表,再有環境變量表
命令參數表通常會先有,然后在命令執行時,該命令會使用當前環境中的環境變量。