操作系統(Operator System)
操作系統有很多種類,但是大的放向有三類。
Windows、MAC、Linux操作系統。
操作系統在計算機中,相當與一個管家,對下合理安排管理計算機資源,對上提供給用戶一個穩定的操作環境。
計算機發展到現在經過不斷的改進,目前使用的是馮諾伊曼體系結構,以內存,CPU,輸入,輸出。
操作系統中內核就是屬於內存管理進程管理等,在操作系統中爲了管理完成一些任務,或者說作業,那麼就會通過描述一個任務,然後進行管理。
進程
概念
是一個程序執行的一個實例,程序正在執行。
從內核來看,是分配系統資源的實體。
描述(PCB)
那麼怎麼來描述一個進程呢?
進程的描述是通過PCB來進行描述。在Linux中描述PCB是通過一個叫task_struct的結構體。PCB中有什麼呢?
有這麼幾個:
1. 標識符:用來描述本進程的唯一標識符,區別其他進程
2. 狀態:用來表示當前進程的狀態,退出碼,退出信號
3. 優先級:相對於其他進程之間的優先級
4. 程序計數器:用於記錄程序的下一條指令的地址
5. 內存指針:其中有代碼和數據相關的指針,還有共享內存塊指針
6. 上下文:進程執行時寄存器中的數據
7. I/O狀態
8. 記賬信息:其中包含各種時間
9. 其他
這裏重點說明一下進程的狀態:
進程的狀態有:
1.R:運行狀態。表示的是進程在就緒隊列或者正在運行。這個是不定。
2.S:睡眠狀態。表示進程在等在某件事情完成。
3.D:磁盤休眠。不可中斷睡眠。
4.T:停止狀態。用來停止該進程。用kill 查看對應的編號
5.X:死亡狀態。進程結束。
6.Z:殭屍狀態。既進程結束但是PCB爲釋放
fork()函數
fork函數用來創建一個進程。這個函數是一個很特別的系統函數,怎麼特別呢?
因爲它調用一次有兩個返回值。
fork 返回值類型是pid_t類型。其實就是一個int型,經過封裝後爲pid_t類型。
而且fork函數在創建出子進程時,父子進程代碼共享,數據各自開闢空間,私有一份,並且採用寫時拷貝。
fork函數返回兩個值,那麼我們怎麼進行操作呢?
fork函數是創建出一個子進程,那麼我們可以用if語句來進行分流。在分流前,我們要瞭解到,fork出來的子進程返回值爲0,而父進程的返回值爲子進程的pid。所以我我們就可以用以下代碼進行分流
int main()
{
pid_t ret = fork();
if (ret > 0)
{
// 父
}
else if (ret == 0)
{
// 子
}
else
{
perror();
}
我們來總結一下fork函數:
1. 一次調用有兩個返回值,父進程返回子進程的pid,子進程返回0
2. 父進程和子進程都從fork執行結束之後的位置繼續執行
3. 子進程以父進程爲模板。採用寫時拷貝
4. 父子進程執行的先後順序,不確定,取決於操作系統調度器
fork()函數創建子進程失敗情況
1)創建進程數達到上限
2)內存滿了,不能有空間進行進程的創建。
殭屍進程
什麼是殭屍進程?
在這裏因爲要說明,殭屍進程也是進程的一個狀態,是Z狀態(zombie)。
怎麼才能進入Z狀態,也就是怎麼產生的殭屍進程。
殭屍進程的產生是因爲在子進程在做完父進程分配好的任務,需要父進程來接受子進程的返回碼,但是父進程沒有接受,這樣子進程就會形成殭屍進程,會以進程終止在進程表中,PCB還在佔用系統資源。
如果父進程還在運行,子進程進入Z狀態,並且佔用系統資源。
產生殭屍進程代碼:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int main()
{
pid_t id = fork();
if (id > 0)
{
// 父進程
printf("%d\n", gitpid());
sleep(10);
}
else if (id == 0)
{
// 子進程
printf("%d\n", gitpid());
sleep(5);
}
else
{
perror("fork");
}
return 0;
}
孤兒進程
什麼是孤兒進程?
孤兒進程簡單的說:
就是當父進程創建出子進程,但是是父進程先退出,子進程還沒退出,就形成了孤兒進程。
如果形成孤兒進程怎麼處理,如果出現孤兒進程,那麼就會由1號進程收養,該進程的父進程變成1好進程Init進程。init進程會每隔一會wait(),直到收回孤兒進程結果,讓孤兒進程正常退出。
用代碼演示孤兒進程:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int main()
{
pid_t id = fork();
if (id > 0)
{
printf("%d", gitpid());
sleep(1);
}
else if (id == 0)
{
printf("%d\n", gitpid(), gitppid());
sleep(10);
}
else
{
perror("fork");
}
return 0;
}
進程優先級
進程優先級是幹什麼用的。爲什麼會有進程優先級。
進程優先級就決定了,進程執行的先後順序,也就是爲了合理的按照一定順序分配系統資源。
對於一個多任務系統,這樣做大大的改善了系統的整體性能。
怎麼查看Linux下的進程:ps -l
需要知道:
UID:代表執行者的身份
PID:代表進程的唯一標識符
PPID:代表當前進程的父進程。
PRTI:代表進程被執行的優先級,值越小越被先執行
NI:代表進程的NICE值。(nice值也可以叫修正數)
關於優先級,難道就只能按照系統給出的執行嗎?自己不可以修改嗎?
不!
我們可以通過修改NICE值進行修改優先級。但是nice值是有修正範圍的是-20到19,四十個級別。
具體怎麼調整:
調整的規則是 新優先級 = 舊有限級 + nice值
1)程序啓動前調整:nice -n -5 ./a.out
2)調整已經存在的進程優先級:renice -5 -p PID號 (意思是把進程號的nice值修改爲-5)
3)用top命令修改nice值:進入top後按r輸入PID號再輸入nice值
最後再總結一下進程的四個性質
競爭性:進程數量較多,而cpu等資源少,就會形成進程間的競爭。合理的競爭會高效的完成任務。也因此有了優先級
獨立性:多進程運行,有着自己獨有的資源,進程與進程之間不會收到影響。
併發性:併發從宏觀上看是同是運行,其實在微觀上看系統的進程是串行運行,因爲CPU的速度比較快,所以就看上去是同時運行。
並行性:並行就是同時運行多個 進程,這是因爲有多個cpu處理器,達到了同時處理兩個進程或者多個進程。就形成了並行。
Linux下的環境變量
環境變量:一般是指在操作系統中用來指定操作系統運行環境的一些參數。
如:我們在編譯代碼鏈接庫時,沒有關心庫在哪?這個就是環境變量在幫助編譯器查找。
常見環境變量
- PATH:命令搜索路徑
- HOME:指定用戶的主工作目錄
- HISTSIZE: 保存歷史命令的記錄條數
SHELL:當前shell,通常是/bin/bash
常用命令
echo $name :name是環境變量名稱,查看環境變量方法。
env: 查看所有環境變量
export:(重點)設置一個環境變量在linux下設置環境變量PATH值
有三種:
1)設置當前進程的PATH,也就是在當前終端窗口有效,如果重新打開終端又回到以前。在命令行輸入 export PATH=$PATH:路徑
2)設置用戶環境變量(linux是多用戶多任務)設置完成就可以在改用戶下是永久的。要到用戶的~/.bash_profile中
添加 export PATH=$PATH:路徑
3)設置全局系統環境變量,到/etc/profile文件中添加。通過系統調用來獲取環境變量
getenv講解
可以通過代碼調用系統調用來獲取某個環境變量。#include <stdio.h> #include <stdlib.h> int main() { printf("%s\n", getenv("PATH")); return 0; }
獲取環境變量PATH的值
如有誤,還望指正,謝謝!