日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

初识linux之进程

發布時間:2024/1/8 linux 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 初识linux之进程 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

目錄

一、馮諾依曼體系結構

1.馮諾依曼體系結構的五大構成

(1)存儲器

(2)輸入設備和輸出設備

(3)運算器和控制器

2.CPU執行

(1)CPU數據來源

(2)內存、CPU和磁盤的數據交換

3.遠端數據傳輸過程

二、操作系統

1.操作系統的概念

2.理解硬件管理

(1)管理的本質

(2)數據獲取

(3)管理的方法

3.對軟件的管理

?4.系統調用和庫函數的關系

?三、進程

1.進程的概念

(1)內存中的進程

(2)PCB(進程控制塊)

(3)進程管理

2.查看進程

(1)windows下的進程查看

(2)linux下的進程查看

(3)結束進程

3.進程的常見調用

(1)通過系統調用獲取進程標示符(進程id和父進程id)

(2)通過系統調用創建進程

4.進程的狀態

(1)程序與內存與CPU的關聯

(2)狀態種類

(3)運行狀態

(4)阻塞狀態

(5)掛起狀態

5.linux中的進程狀態查看

(1)運行(running)狀態

(2)休眠(sleeping)狀態

(3)停止(stopped)狀態

(4)深度睡眠(disk sleep)狀態

(5)追蹤(tracing stop)狀態

?(6)死亡(dead)狀態

(7)僵尸(zombie)狀態

(8)linux下的進程狀態后的“+”含義

6.僵尸進程與孤兒進程

(1)僵尸進程

(2)孤兒進程

7.進程優先級

(1)進程優先級的作用

(2)linux下的進程優先級特點

(3)linux下的進程優先級修改

8.進程相關概念

(1)競爭性

(2)獨立性

(3)并發

(4)并行

9.進程切換

四、環境變量

1.PATH環境變量

(1)將程序路徑添加進該環境變量

2.添加環境變量

(1)添加本地變量

3.取消環境變量和本地變量

?4.查看環境變量內容

(1)查看環境變量

(2)查看本地變量和環境變量

5.windows下的環境變量

6.int main()主函數中的參數

(1)int argc和char* argv[]

(2)char* env[]

五、進程地址空間

1.C/C++地址空間

2.虛擬地址空間

(1)進程認為自身獨占系統資源

(2)系統如何使進程認為自己獨占所有資源

3.虛擬地址

(1)進程地址空間的區域劃分

(2)虛擬地址

4.頁表

5.虛擬地址空間存在原因

(1)保護其他進程和用戶信息

(2)保證進程的獨立性

(3)便于編譯器以統一視角編譯代碼

5.線性地址與邏輯地址

(1)線性地址

(2)邏輯地址


一、馮諾依曼體系結構

在了解linux下的進程之前,我們要先對計算機的構成有一個基本的認識。計算機的組成是由一位名叫馮·諾依曼的數學家提出的。由此,計算機的構成也被叫做“馮諾依曼體系結構”

馮諾依曼體系結構的構成如上圖所示。主要由“輸入設備”“輸出設備”“存儲器”“運算器”“控制器”五個組件構成。因為本段落并不是主講計算機構成,而僅僅是為linux下的進程做鋪墊,因此不會過于細致深入的講解。如果想要更加深入的理解計算機,可以去看《深入理解計算機系統》

1.馮諾依曼體系結構的五大構成

(1)存儲器

存儲器,簡單來講就是存儲數據的地方。而在計算機中,存儲器主要指的是“內存”,計算機中的程序一般都是要加載到內存中去運行。這個“內存”要與我們日常說的磁盤空間的容量相區分。

磁盤空間的容量是外存,但是因為日常中大部分人對計算機的內存和外存區分不清楚,因此統一都是叫“內存”磁盤空間的外存的特點是有“永久性存儲能力”,即存儲的數據不因計算機的關閉而丟失。而內存有一個特點,就是“掉電易失”。指的是如果計算機斷電了,內存中的數據就會丟失

(2)輸入設備和輸出設備

輸入設備輸入設備,簡單來講就是計算機的外設。鼠標、鍵盤、磁盤和網卡等都屬于計算機的輸入或輸出設備。注意,一個外設既可以是輸入設備,也可能是輸出設備。例如磁盤,我們可以從外部輸入數據到磁盤上,也可以從磁盤上讀取數據

(3)運算器和控制器

運算器是用于處理計算機中對數據的數學計算和邏輯運算等的組件。控制器則是完成指令相關操作的組件。這兩個組件沒必要多說,我們只需要知道“運算器 + 控制器 + 部分其他組件 = CPU”,即中央處理器即可

2.CPU執行

在日常編寫代碼的過程中,不知道大家有沒有想過,CPU究竟是如何識別代碼中所要傳遞的信息的。要知道,CPU雖然計算和運行速度非常快,但是其本身只能被動的接受傳輸過來的數據和命令,并按照傳過來的命令執行對應的操作。就如同我們在高中生活中只能被動接受老師的指令進行學習一般。

但是CPU要執行對應的命令,就必須先明白我們傳過去的數據的意思。為此,CPU自身存在一個指令集,該指令集中就是CPU所能執行的命令。同時我們知道計算機底層是由0,1信號組成的。而我們寫代碼編譯的本質其實就是一個翻譯的過程,即將我們的代碼翻譯為“二進制可執行程序”。計算機將該程序傳給CPU,CPU再根據指令集進行對應的操作

(1)CPU數據來源

同時,CPU在讀取寫入數據時,為了提高計算機的運行效率只和“內存”打交道。但是,內存中在一開始是沒有數據的內存中的數據是來源于磁盤,也就是外存的。我們的計算機中的各種程序、文件等數據都是存在磁盤之中,當內存需要時再從磁盤加載到內存中

但是,我們說了在CPU中讀寫數據是為了提高效率。如果每次需要數據都從磁盤先加載內存,再從內存加載到CPU,那么效率其實并不會有什么提升。為此,磁盤中的部分數據其實是會提前加載到內存中的。比如我們的操作系統。其實我們的操作系統也是一個軟件,其數據在關機狀態下存于磁盤中,當我們開機時就會將操作系統的信息加載到內存中。所以其實我們計算機開機的過程就是在加載數據到內存。因此,一個程序要運行必須加載到內存

(2)內存、CPU和磁盤的數據交換

由此,內存也可以看做一個容量很大的緩存,用于與CPU和磁盤之間數據交換的適配。CPU和磁盤都會預先將數據加載到內存,在需要時從內存中刷新數據到磁盤或CPU中。我們經常說的IO過程,其實就是數據從外設中加載到內存和從內存加載到外設中的過程

而內存中需要刷新數據,在有些數據無用時需要刪除數據等等。這些操作內存自身是無法完成的,而是交由操作系統完成。

3.遠端數據傳輸過程

在日常生活中,我們肯定都有過通過QQ或微信給別人發送信息的經歷。但是大家有沒有想過這個從自己的設備發送信息到他人的設備的過程是怎么樣的呢?這個問題當我們了解了馮諾依曼體系結構后就能有一個初步的認知

假設你和你朋友的QQ已經處于登錄狀態,已經加載到了內存當中。現在你和你的朋友之間發了一條“你好”的信息。此時這條信息會先從你的輸入設備,也就是鍵盤或觸摸屏傳輸數據到內存中的QQ的程序中,然后從內存里加載到輸出設備,也就是網卡中。然后這條信息通過網絡傳輸到你朋友的輸入設備網卡中,再從輸入設備中加載到你朋友的內存的QQ程序中,最后從內存中加載到你朋友的輸出設備顯示器上。上述過程不考慮網絡傳輸過程和內存中的數據處理等問題。由此,遠端的數據傳輸可以看成如下圖所示:

二、操作系統

因為操作系統太過龐大,在這里想要完全講完是不可能的,因此此處主要是對操作系統的一個初步理解

1.操作系統的概念

操作系統,簡單來講就是一個進行軟件硬件資源管理軟件。那么操作系統為了要對軟硬件進行管理呢?原因是為了通過合理的管理軟硬件資源(方法),為用戶提供良好的(穩定、高效、安全)執行環境(目的)。

而操作系統的管理主要涉及四個方面:“進程管理”“文件系統”“內存管理”“驅動管理”

2.理解硬件管理

(1)管理的本質

在理解操作的管理之前。我們要先對管理由一個初步的認知。

為了更好的理解,我們在這里舉一個例子。我們在學校里都有一個共同的管理者,也就是校長會對我們進行管理。在這里,校長是管理者,我們則是被管理者。但是,大多數學校里面的人,其實和校長并沒有交集,甚至可能沒有見過面。但是校長依然能夠將整個學校里的人管理的井井有條。這就是說明:“管理者不需要和被管理者直接交互,依然能夠管理好被管理者”

然后,在學校里我們也有輔導員和班長,有人可能認為輔導員和班長也是管理者。但是他們在本質上其實并不是管理者,僅僅只是管理者下的執行者,執行管理者下達的管理方法。因為他們并沒有對管理上重大事宜決策的權力。由此,管理者還需要具備一個因素,就是“擁有對重大事宜的決策權”

同時我們要知道,管理不是亂管理,每項決策的通過執行都需要有對應的依據。以學校管理為例,學校要對學生進行管理,就需要有學生對應的身份信息,學習成績等各類信息。由此,學校的管理就是“對數據進行管理”。而管理的本質也就是“對數據進行管理”

(2)數據獲取

既然管理者要對被管理者進行管理的本質是對數據進行管理,但是管理者和被管理者又不直接接觸,那么被管理者的數據管理者要怎么拿到呢?由此,在管理者和被管理者之間就還有一個執行者

當然,這里是進行了簡化的,實際情況會更加復雜,但是大框架就是這樣。

現在有了執行者這層關系,管理者想要獲得數據,就是下達指令給執行者執行者與被管理直接接觸拿到對應的數據,然后執行者再將獲取的數據交給管理者管理者再通過得到的數據進行決策

將這層關系推到操作系統上,就可以得出操作系統對硬件進行管理時,會通過一層執行者,也就是驅動程序進行管理:

有人可能不太理解什么是驅動。驅動簡單來講,就是使我們的各類硬件可以正常使用的程序。我們的鍵盤、鼠標等硬件并不是插入接口后就能直接使用的。有些人可能就遇見過硬件已經插入接口了,但是無法正常使用,并且計算機中顯示“未查找到驅動程序”“驅動程序損壞”等提示。這就是因為硬件的使用需要操作系統通過驅動程序來進行管理,驅動程序損壞就會導致對應的硬盤無法被正常管理使用。

(3)管理的方法

我們依然以學校為例子。一個學校少則上千人,多則上萬人。校長作為管理者,如果單憑一個人管理數據,無疑是不太現實的。但是學生雖然很多,但是每個學生的數據都是有共同點,無非就是包括姓名、地址、學號、身份證號等各類個人信息。由此,通過這些個人信息我們就可以抽象出一個struct結構體

我們讓學生將自己數據輸入到該結構體中,并利用指針的形式形成一個鏈表。由此,對學生數據的管理就演變成了對鏈表的管理。當我們需要對應學生數據時,直接操作該鏈表即可。通過這種方式,就大大簡化了操作的復雜度。

而這個通過學生的信息特點進行描述的過程就是一個對管理對象的信息進行建模的過程。同時,這個構建結構體的過程在C++中就可以看做是“面向對象”的過程。

通過上述例子,其進行管理的過程其實就是在先對信息進行描述,再根據描述的內容進行建模。因此,管理的方法其實就可以看做是“先描述,再組織”

3.對軟件的管理

首先我們要知道,軟件不僅可以管理硬件,也可以管理軟件。就好比學校里的校長作為一個人,不僅可以管理學校內的各種硬件設備,也可以管理人一樣。

操作系統作為一個軟件,既可以管理計算機內的硬件,也可以管理計算機內的軟件。但是,操作系統 內部其實也是有一定的保護措施的。就好比現實中的銀行,你要去銀行辦理業務,業務員坐在服務窗口后面,你與業務員之間隔著一塊玻璃。這塊玻璃其實就是為了在有危險分子破壞銀行時用于保護業務員的安全的。

操作系統也是同理。但是就像業務員需要為用戶辦理業務,因此開了一個小窗口進行服務

操作系統也是需要為上層用戶提供服務的。但是為了避免上層用戶對操作系統底層數據的破壞,也是提供了一個“操作系統接口”來為用戶提供服務。要注意的是,這個接口其實就是系統調用接口,因為操作系統是用C語言寫的,這個系統調用接口其實也是“C式接口”

當然,雖然操作系統提供了各式各樣的系統調用接口,但是對于大部分用戶來說,直接調用系統接口進行操作還是過于復雜和困難,由此又出現了“用戶操作接口”。這個接口由shell外殼C/C++的lib部分指令組成。用戶使用計算機就是通過各種指令等操作去調用“用戶調用接口”,再用用戶調用接口去調用“系統調用接口”

?4.系統調用和庫函數的關系

(1)開發角度來看,操作系統對外會表現為一個整體,但是會暴露自己的部分接口,供上層開發使用,這部分由操作系統提供的接口,叫做系統調用

(2)系統調用在使用上,功能比較基礎,對用戶的要求也相對較高。所以,有心的開發者可以對部分系統調用進行適度封裝,從而形成“庫”。有了庫,就很有利于更上層用戶或者開發者進行二次開發

?三、進程

1.進程的概念

進程,指的就是一個運行起來(即加載到了內存中)的程序,就叫做進程。也可以簡單理解為在內存中的程序就是一個進程。

而我們所說的程序,其本質就是文件,這些文件存放在磁盤上

(1)內存中的進程

在之前我們已經了解到,磁盤中的程序會加載到內存中,但其過程并不是我們所想象的那么簡單。因為加載到內存中的程序,一般來講并不會只有一個,都是多個進程同時存在于內存中

如果有疑惑,可以打開電腦上的任務管理器,這里面就有進程查看窗口

并不是說如果你打開電腦什么軟件都不開,就不會有進程。只要你的電腦處于開啟狀態就會有系統進程在內存當中,少則十幾個數十個,多則上百個

對于如此多的進程,操作系統則需要對這些進程進行管理,包括分配空間的大小,分配的空間的位置等各種各樣的信息都需要操作系統進行管理。而我們之前說過,管理的方法是“先描述,再組織”

(2)PCB(進程控制塊)

為了方便對這些進程進行管理,操作系統也根據這些進程的一些共同信息進行整理歸類,形成了“PCB”,也就是“進程控制塊”。進程控制塊我們現在可以簡單的看為就是一個結構體,這個結構體里面包含了進程的各類屬性和該進程對應的代碼、屬性地址(這些屬性在磁盤中的可執行程序中是沒有的,會在加載到內存時自動形成):

由此,每一個進程在內存都擁有一個“struct task_struct*”。至于為什么是結構體而不是類,是因為操作系統是由C語言編寫的,C語言中并沒有類的概念

(3)進程管理

當我們理解的“進程控制塊”后,就可以更好的理解進程在系統中的交互了。

當一個程序從磁盤加載到內存中時(注意加載的僅僅只是程序的執行代碼等內容),會對應生成了一份“進程控制塊”,該控制塊會指向內存中對應的進程。當存在多進程時,這些控制塊以鏈表的形式相互連接。如果CPU想調用某個進程,內存就會通過控制塊鏈表找到對應的控制塊,再由控制塊找到對應進程的執行代碼發送給CPU:

由此,所謂的對進程進行管理,就變成了對進程對應的“PCB”進行相關管理,進而變成了對鏈表的增刪查

進程控制塊的內核當中的struct task_strcut內核結構體,是用于描述進程的結構體。當我們形成進程時,該內核結構體會為我們創建一個內核對象:”task_struct 對象”。然后再將該結構與我們的代碼和數據相關聯起來,進而完成“先描述,再組織”的工作

由此,我們可以得到進程其實就是“進程 = 內核數據結構(task_struct) + 進程對應的磁盤代碼”

2.查看進程

(1)windows下的進程查看

在windows下要查看進程是很簡單的,直接打開任務管理器就可以看見:

(2)linux下的進程查看

為了便于查看,我們現在寫以下一個會循環打印“i'm a process”這句話的程序:

?我們先生成一個“myprocess”程序,此時該程序還沒有運行,僅僅只是一個在磁盤上的二進制文件:

?我們執行該程序,此時它就變成了一個進程:

但是我們現在雖然知道它是一個進程,但卻無法查看該進程。要查看該進程主要用以下方法。

1.執行“ps ajx | grep 程序名”命令

該命令中的“ps ajx”是顯示系統中的所有進程。整條命令是用于篩選帶有對應“程序名”字樣的進程。我們執行后就可以找到對應的進程:

如果不理解這里面顯示的信息,可以輸入“ps ajx | head -1 && ps ajx | grep ‘程序名’”。該命令會輸出對應的數據的標題:

(3)結束進程

要在linux下結束一個進程非常簡單,我們直接執行“kill -9 PID號”即可:

3.進程的常見調用

(1)通過系統調用獲取進程標示符(進程id和父進程id)

1.進程id和父進程id

在linux下,每個程序都有自己的進程id和父進程id

在了解進程id和父進程id之前,我們要先了解兩個函數:getpid()getppid()。第一個函數是用來獲取進程id的, 而第二個函數則是用來獲取父進程id的:

這里的返回值是“pid_t”,我們暫時將其理解為返回一個整數即可。

為了方便演示,我們用以下程序演示:

該程序的運行結果如下所示:

可以看到,此時就將該進程的pid和ppid打印出來了。但是,如果我們多執行幾次:

我們就會發現,該程序的進程id會不斷改變。這很容易理解,因為進程結束后重新加載到內存中都會有一個新的進程id。就好比你高考考上了一個大學,你入學后會給你一個學號,但是你不滿意該學校,復讀了一年又考上了同一個大學,此時又會給你一個學號,但是這兩個學號是不一樣的。

進程id改變我們能理解,但奇怪的是父進程id卻沒有改變。既然如此,我們現在就輸入“ps ajx | head -1 && ps ajx | grep 29513”命令:

可以看到,在進程名字這一塊,29513顯示的是“bash”。這其實就是一個“總進程”。在操作系統啟動時,操作系統就已經為我們指派了一個進程,我們所有的進程都是在該進程下執行的“子進程”。而該機制的目的就是為了避免我們的進程有問題時,對系統使用產生影響

而這里的這個“bash”進程,其實就是我們的shell。我們執行“kill -9 進程id”命令來結束該進程:

可以看到,當我將該“bash”進程結束掉后,我的linux賬戶就直接退出了。當然,在某些云服務器上可能不會退出,但也會導致命令無法使用

注意:命令行上啟動的進程,一般它的父進程沒有特殊情況的話,都是bash

(2)通過系統調用創建進程

1.fork()函數調用

要通過系統調用創建進程,直接調用fork()函數即可,該函數的作用就是創建一個進程

雖然我們知道了fork()函數,也知道了該函數的作用,但我們不知道該函數執行后會出現什么現象。因此,我們用以下程序來進行測試:

在執行該程序前,我們要先知道,在fork()函數調用前,該進程只有一個父進程。而在fork()函數調用后,才會新形成一個進程,此時就是“父進程 + 子進程”兩個進程。

現在我們來執行該程序:

可以看到,我的程序里面僅僅只是打印一句話,但是這里卻打印了兩句話,并且第一句話中的子進程id就是第二句話的父進程id

這就是因為fork()創建了一個進程。第一個進程的父進程很明顯是“bash”,而第二個進程由于是在該程序中創建的,因此它的父進程就是進程10755。這也就說明了fork()確實能創建進程

2.fork()函數的返回值

從上面的程序中我們確實可以證明fork()函數可以創建進程。但是這種使用方式卻沒有什么意義,因為將fork()函數之后的代碼執行兩次并沒有什么用。

因此,現在我們來看看該函數的返回值。

首先是函數的返回值類型:

可以看到,這個函數的返回值是“pid_t”,前面也說過,這個返回值看成返回一個整數即可,沒什么好奇怪的。

接下來我們看看該函數對返回值的解釋:

在這里我們只用看成功時的返回值,失敗的現象我們就先不考慮。可以看到,在這里的返回值解釋中說到,“如果成功,就把子進程的pid返回給父進程,并將0返回給子進程”。那么我們修改一下程序如下圖來測試一下:

?然后我們執行該程序:

可以看到,執行結果確實是將子進程的pid返回給了父進程,并將0返回給了子進程。一眼看上去沒有什么問題,和手冊里面的返回值解釋的一模一樣。

但是,我們在學習C或C++時說過,“一個變量在同一時間只能有一個返回值”。而在這里,在該程序沒有對返回值進行任何修改操作的情況下,竟然讓變量在同一時間擁有了兩個返回值。這就是問題所在。

3.fork()的使用場景

對于上述情況,我們現在是無法理解的,因為我們對進程的理解還不夠深入。但我們理解了進程控制之后才能對上述情況有個更清晰的認識。

因此既然我們無法理解現象,但我們可以用它。現在我們寫如下一個程序:

如果id == 0,我們就循環打印子進程。如果id > 0,就循環打印父進程。注意,我這里寫的是兩個死循環

然后來執行該程序:

可以看到這里程序在正常運行,這種同一程序中多個進程同時運行的現象就叫做“多進程”

但是我們要注意到,該程序不僅打印了子進程,也打印了父進程。我們的程序寫的是一個if判斷,并且里面的內容是死循環打印。按道理來講同一時間只會有一個if else判斷成立。但是,在這里這兩個判斷條件同時成立并且都在死循環打印

這種現象其實就說明了兩個點:

(1)fork()執行后,會有父進程和子進程兩個進程在執行后續的代碼

(2)fork()之后的代碼,會被父進程和子進程共享

意思就是,在這里是兩個不同的進程在執行相同的代碼,根據fork()返回值的不同執行了各自不同的部分。而這種通過返回值的不同,使父子進程執行后續共享代碼不同部分的編程方式就叫做“并發式編程”

4.進程的狀態

在理解進程狀態前,我們要先理解CPU是如何調度進程和進程時如何存在于內存中的

(1)程序與內存與CPU的關聯

首先我們要知道,我們的各類硬件都是通過驅動程序來支持運行的,每個驅動程序在磁盤中都會一個對應的“PCB進程結構體”,這個結構體中包含了對應的硬件的所有屬性信息

而磁盤中的程序要運行也是同樣的。磁盤中的程序啟動后會進入內存中變成進程,此時該進程中包含了運行程序的代碼等內容。而當一個程序變成一個進程后,內存中就會對應生成該進程的“PCB進程結構體”,該結構體中包含了對應進程的各類屬性對應進程的代碼地址

當這些進程要運行時,就必需要由CPU進行調度執行。但是我們的CPU只有一個,哪怕你是多核,你的CPU的數量依然無法與進程的數量相比。并且一個CPU一般來講只能同時運行一個進程。那么有人就會奇怪了,既然一個CPU同時只能運行一個進程,那么為什么我們的計算機上能有數十上百個進程在同時運行呢?

這是因為CPU雖然同時只能運行一個進程,但是它的運行速度非常快,運行一個進程的速度是以納秒甚至微秒為單位的。因此,CPU在運行進程時可以看成是在不間斷的循環跑所有進程,一個進程跑完后立刻下一個進程。就好比我們在公司面試時一次面試只能進去一個人,面試官就是CPU,而我們就是那一個個進程。同時因為其速度非常快在感官上就會給我們所有進程在同時運行的錯覺,其實這些進程都是一個一個的運行的。

既然進程需要循環跑,那么就必定需要按照某個順序來跑,不然CPU無法知道自己應該接著運行哪個程序。由此,又有了“運行隊列”的概念。從名字就可以知道,這是一個隊列。在這個隊列中包含了指向進程結構體的指針和一些其他需要的屬性。運行隊列按一定順序將這些結構體鏈接在一起,CPU運行進程時就按照該運行隊列中的順序運行

要注意,在運行隊列中的是“PCB結構體”,而不是進程本身。就好比我們找工作投簡歷時,發給公司的是我們的簡歷,公司在對簡歷排序篩選時也是對我們的簡歷進行排序,而不是讓我們本人過去對我們進行排序。

?現在有了對上述的內存中的進程與CPU的關聯的知識后,我們就能很容易的理解各類進程狀態了

(2)狀態種類

進程有很多種狀態,如運行新建就緒掛起阻塞等待停止掛機死亡等各類狀態。在這里不會將所有狀態都講解一遍,而是選擇其中比較常見的幾種狀態講解

(3)運行狀態

運行狀態,指的就是“處于運行隊列中的進程的狀態”。換言之,只要一個進程在CPU的運行隊列中,那么該進程就處于運行狀態,都是“R”狀態無論它是否真的在CPU中運行。就好比我們面試時,只要在面試房間外排隊的人都將自己調整為了面試狀態準備面試,無論這些人是否是在面試房間內接受面試

(4)阻塞狀態

我們要知道,CPU在運行進程時,這些進程不僅需要CPU中的資源,也可能需要硬件資源。就比如我們在QQ上和別人聊天,此時QQ處于運行狀態,需要占用CPU資源,同時我們發送信息也需要網卡,顯示器等硬件資源。

當然,有人可能會覺得既然進程需要硬件資源直接去用就行了。但是硬件資源的調用速度非常慢,當然這個慢是與CPU的速度相比。因此就可能出現CPU在調用某個進程時,該進程還需要用到硬件資源而使CPU不得不停下等待的狀況。為了應對這個問題,在我們的硬件的“PCB結構體”中就還有一個“等待隊列”。該隊列和CPU的“運行隊列”差不多,是用于等待硬件進行調用完成進程資源需求的:

假如現在在CPU中有一個正在運行的進程想要向磁盤寫入數據,那么CPU就會將該進程從運行隊列中剝離出來,將其放到磁盤的等待隊列中,然后繼續執行其他進程。如果磁盤此時正在為其他進程服務,該進程就會在等待隊列中等待。就好比我們去銀行辦理業務,業務窗口的工作人員告訴我們說我們需要先去另一個窗口填一個表才能幫我們辦理對應業務,此時我們就直接去另一個窗口填表,如果沒人就直接填,有人就排隊等待。但是我們原來的那個業務窗口不可能等我們填完表幫我們辦理好后再幫其他人辦理業務,而是在我們去另一個窗口時接著幫其他人辦理業務。這種進程在硬件的等待隊列中等待硬件資源就緒,就叫做進程處于“阻塞狀態”

當該進程的資源使用完成后,操作系統就會將該進程從磁盤中調出來,將其狀態改為“運行狀態”后重新加入CPU的運行隊列運行。

從這里我們也可以看出來,其實進程的不同狀態指的就是“進程在不同的隊列中”

注意,進程在不同隊列中指的是進程的“PCB結構體”在不同隊列中,而不是進程本身

(5)掛起狀態

我們說過阻塞狀態就是一個進程因為需要使用硬件資源而進入對應硬件的等待隊列時的狀態。

但是如果此時一個硬件的等待隊列中存在多個等待進程,那么就會導致這些進程雖然無法進入CPU的運行隊列運行,但也無法使用硬盤資源,只能等待。

此時對應進程的“PCB結構體”雖然在硬盤的等待隊列中無法運行,但是其本身的數據依然在內存中占據空間。因此對于這種占著磁盤空間卻什么都沒干的進程,內存為了騰出容量供其他進程使用,就會暫時將該進程的代碼、執行進度等數據從內存中挪到磁盤的一塊專門存放這種未運行進程數據的空間內

而這種在內存中的一個進程的數據被從內存中暫時轉移到磁盤內的行為,就叫做“掛起”。而此時的進程就是處于“掛起狀態”

當對應進程的進程結構體進入硬件使用完資源被重新放入運行隊列時,該進程的資源就會被從磁盤內重新轉移到內存中。這種對進程數據的轉移就叫做“內存數據的換入換出”

當然,與掛起相關的還有“阻塞掛起狀態”“準備掛起狀態”等。有興趣的可以自行了解,基本除了“運行狀態”外,其他的狀態都可以與“掛起狀態”相結合

5.linux中的進程狀態查看

如果大家有興趣,可以去linux中的內核源代碼中搜索“task_state_array”來查看liunx下的進程狀態的表示。這里就不去查找了,linux下的進程狀態表示就如下圖:

(1)運行(running)狀態

在linux下,進程的運行狀態用“R”表示。

為了方便看到進程狀態,我們現在寫以下一個死循環程序:

?注意,因為這里程序是在死循環運行,除非我們停下程序,不然在該窗口下是無法執行命令的。因此我們要先復制窗口,然后在另一個窗口下執行命令

右擊你的賬戶選項卡,選擇里面的復制會話即可

我們將該程序運行起來后,輸入“ps axj | grep 程序名”命令:


此時我們可以看到,在該myprocess程序下的狀態欄下,就有一個“R+”的符號,這就表示該程序處于“運行狀態”。至于“+”號,我們暫時不用管。下面的那個進程時grep命令的進程,也不用管

(2)休眠(sleeping)狀態

睡眠狀態在linux下的符號是“S”

我們現在準備以下一個死循環打印程序:

現在我們來運行該程序:

此時該程序在不停的打印數據。然后我們在另一個窗口輸入“ps ajx | grep 程序名”命令:

?可以看到,現在該程序的運行狀態就變成了“S+”,即“睡眠狀態”。那大家就會覺得很奇怪,明明該程序一直在運行,為什么這里顯示的不是“運行狀態”而是“睡眠狀態”

這其實是因為該程序需要循環打印一條消息,要打印該消息就需要使用顯示器的資源。但是顯示器作為一個硬件,其運行速度比CPU的速度慢很多。可以說在該程序中有99%的時間都在訪問顯示器,只有1%的時間是CPU運行該進程。當我們查看該進程時,極大可能查看到的都是該進程在訪問顯示器時的狀態,而非在CPU中運行的狀態。因此當我們查看一個需要訪問硬件的進程時,基本都是睡眠狀態。“睡眠狀態”也可以看做就是“阻塞狀態”

(3)停止(stopped)狀態

停止狀態一般被視作掛起狀態或阻塞狀態的一種,但是linux將該狀態單獨拿出來了

我們繼續運行以下程序:

然后我們在另一個窗口中輸入“ps axj?| grep 程序名”命令:

此時它依然是“休眠狀態”。然后我們輸入“kill -l”命令,該命令可以查看kill命令所能帶的選項

此時我們可以看到,在該命令的選項中有一個“19”號命令,可以用于暫停。然后我們輸入“kill -19 進程pid”命令。如果不知道哪個是進程pid,可以輸入“ps axj | head -1 && ps axj | grep 進程名”進行查看:

當我們輸入暫停命令后,可以看到,此時我們的程序下方就出現了“Stopped”提示,表示該進程已被暫停。然后我們輸入“ps axj | grep 進程名”命令:

此時我們就可以看到,該進程的進程狀態時“T”,即暫停狀態?

當然,既然能暫停,就可以繼續,如果我們想進程繼續運行,就可以輸入“kill -18 進程pid”來運行:

此時該進程又重新變成了“S”,即睡眠狀態

(4)深度睡眠(disk sleep)狀態

深度睡眠狀態是一種特殊的狀態,在linux中用“D”標識,與“睡眠狀態”相對應。簡單來講,“睡眠狀態”的進程我們是可以將它終止的,但是“深度睡眠狀態”的進程無法被終止。這種狀態是為了防止如磁盤這類進程被操作系統終止導致數據丟失用的。

要更好理解“深度睡眠狀態”,在這里我們舉一個場景:假設某一天,我們有一個進程A,該進程需要向磁盤寫入數據。于是進程A就帶著自己的數據地址來到磁盤,讓磁盤幫它處理。但是此時我們的內存中存在著許多進程,使得整個內存已經快滿了面臨內存不足的情況。操作系統作為管理這些的存在,為了騰出內存空間供其他進程使用,于是將很多進程都“掛起”了。

但是掛起很多進程后還是無法解決內存不足的問題,于是操作系統就開始刪除那些占著內存不干事的進程。而進程A剛好就在等磁盤寫入數據,無所事事。于是操作系統來到進程A身邊,將進程A結束了。過了一會兒磁盤寫入數據結束了,但是不知道什么原因寫入失敗,磁盤就想將寫入失敗的事實返回給進程A,但是進程A此時已經被結束了,磁盤無法返回數據。但是磁盤不能因為無法返回數據就停下不解決其他進程的問題,于是磁盤就將這些失敗數據扔掉了。

等到用戶需要這些數據時,就發現磁盤中沒有對應的數據,并且了解到是因為操作系統為了解決內存不足的問題將進程A結束了,導致無法及時發現數據未寫入。于是用戶就將進程A設置為了“深度睡眠狀態”,該狀態下的進程無法被操作系統刪除,同時也無法被用戶刪除

“深度睡眠狀態”我們在平時是很少見到的,基本只有在“高IO”“高并發”狀態下才會看見。當然,不要覺得這個進程狀態很好用,如果一個公司的服務器中的進程出現了大量的“D”狀態,就說明該服務器正處于“崩潰”的邊緣,也就是我們平時聽到的一些公司在高訪問下的“服務器崩潰”“宕機”。這種情況解決起來是非常困難的,因為無論是操作系統還是用戶都不會干涉這種狀態的進程。要想解決只能慢慢減輕服務器的負擔使服務器緩過來或者等程序自己醒來甚至斷電重啟

如果大家想看看該狀態,可以輸入“dd”命令。該命令會形成一個幾十上百g臨時文件。大家最好不要輕易嘗試該命令,因為如果你的機器空間不夠,執行該命令后你的系統很有可能會直接崩潰掛掉

(5)追蹤(tracing stop)狀態

追蹤狀態在linux下是用“t”表示,意思是該進程正在被追蹤

我們寫如下一個程序,該程序會打印4次“追蹤測試”:

然后我們對該程序進行調試,并在第8行處打上斷點:

現在我們運行該程序,該程序就會在第8行停下:

此時我們再在另一個窗口查看該進程的狀態:

可以看到,該進程的進程狀態顯示的是“t”,就是我們的追蹤狀態,此時該進程的運行正在被追蹤。而該狀態的存在就是我們能夠調試程序的原因。該狀態下程序停止,等待用戶查看此時產出的數據后后續操作

?(6)死亡(dead)狀態

該狀態在linux中用“X”表示,意思是一個進程的死亡。理解起來很簡單,就是一個進程的結束

但是我們很難去驗證該狀態的存在,因為在linux下只要一個進程死亡,系統就會立刻或者延遲回收該進程的空間,雖然有可能延遲,但是是相對于系統速度而言的,對我們來講就是一瞬間的事

(7)僵尸(zombie)狀態

僵尸狀態是linux下一個非常特殊的狀態,用“Z”表示,用于表示一個進程已經退出了,但是它占用的資源還未釋放

舉個例子,你是一個小區的住戶,你每天都會出門鍛煉,你出門的時候都會和你的鄰居打個招呼問個好。但是有一天,你去給你這個鄰居打招呼時無論怎么喊都沒人理你,于是你推開門進去,發現你的鄰居已經不動了。看到這個情況你趕緊打電話給110和120,120的人來后查看了以下,確認這個人已經去世了。此時警察來了,封鎖了整個現場并對你的鄰居進行調查看看是什么情況。等到警察和醫院把你的鄰居的死因等等信息都獲取后,才會通知他的家屬讓他們將人帶去埋了。

在這個例子中,我們的鄰居就好比是進程110和120就好比是該進程的父進程操作系統鄰居去世就是該進程結束了,但是進程雖然結束了,它的數據還會在內存中保留下來供父進程或操作系統獲取。等它們信息獲取完后,才會由父進程或操作系統將該進程所占用的資源釋放掉。而這個進程已經結束但資源未回收的狀態,就叫做“僵尸狀態”

要查看僵尸狀態也很簡單,我們寫一個子進程已經結束但父進程未結束,無法回收空間的程序即可:

該程序會創建一個進程,并根據返回值執行不同的操作,子進程會在5s后退出,但是父進程會死循環執行

等5s子進程結束后我們再查看該子進程的狀態:

此時可以看到,該子進程的狀態就是“Z+”,處于僵尸狀態。同時,該進程的名字后面還有“defunct”提示符,表示“該進程已失效”

僵尸狀態是在一般情況下是每個進程在結束時都會短暫存在的狀態,這里的短暫是以系統角度來說的,正常情況下我們是看不到的。

(8)linux下的進程狀態后的“+”含義

我們以以下一個死循環程序為例:

該程序運行后是休眠狀態“S+”,沒什么好說的:

然后現在輸入“kill -19 進程pid”將該程序暫停

此時該程序進入了暫停狀態。然后我們再輸入“kill -18 進程pid”命令讓該程序繼續運行后并查看它的進程狀態:

這時我們就會發現,該進程雖然繼續運行了,但是它的進程狀態不是顯示的“S+”,,而是“S”。然后我們在該進程運行的窗口下按下“ctrl c”其他各類指令

此時我們會發現,無論我們按下多少次“ctrl c”都無法結束該進程,并且在這個窗口下我們還能執行各種命令,但是這個打印進程就是不會停止

原因就是因為此時該進程已經變成了一個后臺進程,一直都在后臺運行“ctrl c”命令是結束前臺進程的命令,無法結束后臺進程。因此在進程符號中有“+”的就是前臺進程沒有“+”的就是后臺進程

如果我們想結束該后臺進程,就要使用“kill -9 進程pid”命令來結束

6.僵尸進程與孤兒進程

(1)僵尸進程

僵尸進程,簡單來說就是處于僵尸狀態的進程的資源一直未被回收。雖然已經退出的進程的信息都被保存在“PCB結構體”中,但結構體的維護也是需要資源的

如果一個進程的已經退出了,但是它的父進程或操作系統一直都沒有將它所占用的資源回收,就會導致應該釋放的資源無法釋放。如果一個父進程創建了很多子進程卻不回收它的資源,就會使得內存中的可用空間越來越小,進而造成內存泄漏問題。

所以僵尸進程是我們必須要避免和解決的問題。

(2)孤兒進程

僵尸進程父進程還未結束時,子進程先結束導致子進程的資源無法釋放。而孤兒進程則是子進程未結束,父進程先結束,導致子進程沒有人管,就可能出現當子進程結束時,其資源無法釋放。為此,linux下在這種子進程未結束而父進程先結束的情況下,會讓操作系統領養子進程,待子進程結束后的資源由操作系統來釋放

我們寫以下一個程序來測試:

現在運行該程序,該程序會循環打印子進程和父進程的pid及其ppid。然后我們再在該程序運行時查看它的狀態:

此時兩個進程都是“睡眠狀態”。現在我們輸入“kill -9 進程pid”命令,將父進程結束,并查看進程的狀態:

可以看到,此時父進程就結束了,但是子進程還在。有人可能就會奇怪,子進程結束時父進程未結束都會導致該子進程成為“僵尸進程”,但這里的父進程結束后就直接結束了,沒有成為“僵尸進程”。原因是所有的進程都是在父進程“bash”下運行的,上面的那個父進程也不例外。但是“bash”父進程和普通的父進程不一樣,它比較負責任,當它的子進程結束時,會自動釋放子進程的資源

我們可以注意到,該子進程的狀態從“S+”變成了“S”。就這說明當子進程的父進程先結束時,未結束的子進程會變成“后臺進程”。此時的子進程無法用“ctrl c”的方法結束,只能用“kill -9 進程pid”命令來結束

如果眼尖的人就會發現,剩下的子進程的ppid變成了“1”

我們輸入“ps ajx | head -1 && ps ajx | grep systemd”查看一下操作系統:

可以看到,操作系統的pid就是1,這就說明“當一個父進程先結束,但其子進程未結束時,該子進程會被操作系統領養”。對于該子進程后續的資源釋放也就都是有操作系統來進行

7.進程優先級

進程優先級這一概念比較簡單,并且用戶能對進程優先級的操作和干涉也是比較少的。因此進程優先級不必過多了解

(1)進程優先級的作用

優先級的概念就簡單,就是確定誰先誰后的問題。進程優先級也是同樣的。因為在計算機中,資源總歸是少數, 而要使用資源的進程才是多數。如果不確定進程優先級,將哪個進程先執行哪個進程后執行劃分出來,就可能出現混亂,導致資源被隨意占用

(2)linux下的進程優先級特點

在一般情況下,系統的進程優先級都是用一個數字來確定的。但是在linux系統中的進程的優先級是用兩個數字來設置。

至于為什么用數字來設置,就好比我們去學校食堂吃飯,當你點餐后每個窗口都會給你一個寫著你的號碼的小票,這個號碼就是廚師做你的飯的次序,也就是廚師做飯的優先級

(3)linux下的進程優先級修改

linux下的進程優先級是可以修改的。在實際修改之前,我們先寫以下一個死循環程序:

我們將這個程序運行起來后,再在另一個窗口輸入“ps -la”查看進程的優先級

在這里面的“PRI”表示priority,即“優先級”“NI”表示“nice”,是用于修改的優先級的。在默認情況下,linux下的普通進程的優先級“PRI”都是80“NI”0

并且在linux下,進程的優先級 = 老的優先級 + NI值

現在我們輸入“top”命令修改優先級(如果使用top修改的權限不足,可以嘗試用“sudo”提權再修改):

輸入“top”命令后會出現以上界面(該界面未截全,下面還有很多進程)。在這個界面按下鍵盤上的“r”

?就會彈出這個輸入行。在這里輸入你要修改的進程的pid(注意,要用你的字母鍵盤上面的那一行數字輸入,右邊的數字鍵盤可能無法輸入):

有以上輸入行后,就可以輸入你要設置的優先級了。在這里我們將優先級設置為-100

設置好后按下“q”退出該界面。然后在輸入“ps -la”命令查看優先級:

可以看到,雖然我們設置的優先級是“-100”,但是該進程的優先級“PRI”僅僅變成了“60”,而“NI”則變成了“-20”

然后我們再將該進程的優先級設置成100后再來查看該進程優先級:

此時“PRI”變成了“99”,而“NI”則變成了“19”。這就說明,在linux下用戶所能設置的優先級僅僅是40個維度,即“60~99”。這同時也說明了用戶能對進程中的優先級干涉是很少的

同時要記住,在linux下,雖然說進程的優先級 = 老的優先級 + NI值,但是這個“老的優先級”其實并不是我們設置完后的優先級值,而是其默認的80

比如此時我們的程序優先級是99,我們再將其設置為1

此時的優先級是“80 + 1 = 81”,而非“99 + 1 = 100”?

8.進程相關概念

(1)競爭性

一個系統的進程是非常多的,動則數十上百個。但是在我們的計算機中,CPU都是很少的,一般只有h3一個。所以進程之間為了使用資源,是具有競爭屬性的。為了更高效的完成任務,更合理的競爭相關資源,便有了優先級

(2)獨立性

在多進程運行下,每個進程獨享各種資源,多進程運行期間互不干擾。

比如我們的手機上我們可以同時打開如QQ、微信、b站等各類軟件。但是一個軟件的退出或崩潰不會影響到其他軟件。這就是因為各個進程之間具有獨立性

(3)并發

多個進程在一個CPU下采用“進程切換”的方式,在一段時間內,讓多個進程都得以推進,稱之為并發

在我們的計算機中,一個CPU在同一時間只能有一個進程運行。但是CPU并不是在運行完一個進程后再運行下一個進程。而是設置了一個“時間片”來限制。假如這個時間片是10毫秒,那么就說明每個進程都只能在CPU中運行10毫秒。時間一到,無論該進程有沒有運行完,都必須切換成下一個進程。當輪到同一個進程時就從其上次運行的地方開始再運行10毫秒,如此循環往復

(4)并行

雖然一般的計算機只有一個CPU,但有些計算機是會有2個甚至更多的CPU的。而一個CPU中同一時間只能有一個進程運行,當存在多個CPU時,就會出現多個進程同時運行的情況,這就叫做“并行”

要將“多CPU”“多核”相區分。“多核”中的“核”指的是CPU中的內核處理器,而非CPU本身。也就是說,“多核”指的是一個CPU中有多個“內核處理器”,而非多個CPU

9.進程切換

在并發中我們說了, 進程在CPU中運行時,并不是一個進程運行結束后才運行下一個進程。而是設置一個“時間片”每個進程都會跑時間片所規定的時間。如果時間片是10毫秒,那么每個進程都跑10毫秒,無論該進程有沒有結束

該機制的作用就是為了防止某些進程長期占用CPU導致CPU無法執行其他進程。舉個例子,我們有時會寫一個死循環程序。當執行該程序時,如果CPU要跑完該進程才切換為其他進程的話,我們就無法進行其他任何操作,因此此時CPU已被該死循環進程占用,且CPU同一時間只能運行一個進程,無法切換為其他進程。但實際上并不會出現上述情況,原因就是有時間片的存在,導致該死循環進程執行一定時間后就被切換成其他進程了

現在我們知道了CPU會進行進程切換。但是CPU是怎么知道上一個進程執行到什么地方了呢?其實,在CPU中是存在一套寄存器的,注意是一套,而不是一個。在這套寄存器里面有著保存各類數據的寄存器。當我們的進程要切換為下一個進程時,CPU中的寄存器會將該進程執行的指令的下一條執行的地址保存下來,與此同時被保存下來的還有該進程運行所產生和需要的各類臨時數據,這些數據被存放在“PCB結構體”中,當然這一說法并不準確“PCB結構體”中并沒有空間來保存這一數據,但現在我們暫時可以理解就保存在結構體中。

寄存器中的數據,每當一個進程加載進CPU時都會被覆蓋,因此需要有這種恢復機制。就好比我們定義一個變量,這個變量只能有一個值,當有其他值給這個變量時,原來的值就會被覆蓋

因此,當進程進行切換時,將執行到的指令地址和各類臨時數據保存下來的操作,叫做“上下文保護”。當進程在恢復運行時,通過PCB結構體將上一次執行的指令和數據恢復到寄存器中并繼續運行的操作叫做“上下文恢復”

有人可能會說,一個寄存器的空間也就4個字節8個字節,雖說CPU中不止一個寄存器,但是我們寫程序時會定義很多個變量,有很多的值。甚至我們電腦上幾十個G的軟件都有,寄存器怎么保存的下呢?其實寄存器雖然空間小,但是其速度非常快。并且當一個程序運行時,它在某個時間段只會執行固定數量的指令或某一行代碼。而寄存器的內部只會保存當前進程在當前時間所執行的指令和需要的數據,在這些指令之前和之后的那些不需要使用的指令,寄存器都不會保存。因此,寄存器中的數據是一直變化的

四、環境變量

環境變量其實就是指“操作系統為了滿足不同的應用場景而預先在系統內設置的一大批的全局變量”。同時我們要有一個認識:“環境變量其實就是字符串”。

在了解環境變量之前,我們要先理解一個問題,就是在linux下我們自己寫的程序和程序中的指令有什么不同?我們輸入分別輸入“file /usr/bin/ls”“file myprocess”查看系統命令ls和我們自己寫的myprocess程序:

可以看到,系統命令其實也是一個程序,我們使用系統命令時其實就是在運行一個程序。當我們運行一個程序我們自己寫的程序時,我們必須要讓系統知道該程序所在路徑,因此“./”的作用其實就是提供“相對路徑”,告訴系統該程序就在當前路徑內

但是系統命令作為一個程序,卻不需要帶上“./”。這不是因為系統不需要去找它的路徑,而是因為系統幫我們到默認路徑上去找了

因此,如果你想讓你的程序可以不帶“./”運行,就可以執行“sudo cp 程序名 /usr/bin/”命令,該命令會把你的程序放到默認路徑

可以看到,在上圖中,我們用程序名去執行會報錯

但是當我們執行cp命令后(如果是普通用戶就需要加sudo,root用戶則不需要):

此時我們就無需帶“./”就可以執行對應程序。這也就說明了linux下的系統命令其實就是存在于“/usr/bin/”路徑下的程序

當然,并不建議大家將自己寫的程序添加到該默認路徑下,因為你自己寫的程序不夠安全,也沒有經過檢測,很可能會污染命令池

如果你想刪除在默認路徑下的程序,執行“sudo rm -f /usr/bin/程序名”即可

1.PATH環境變量

環境變量應用于系統的不同場景,我們以下面的一個例子來理解環境變量中的“PATH”

現在我們知道了為什么系統命令無需帶“./”。但是系統是如何找到對應的默認路徑的呢?這其實就是因為系統中定義了一個叫做"PATH"的環境變量

我們輸入“echo $PATH”進行查看:

可以看到,在該環境變量中存在很多路徑,我們的系統其實就是從這些路徑里面去找對應的命令,如果沒有找到就會報錯。我們的ls等命令無需帶“./”也是這些命令的所在路徑在該環境變量中

(1)將程序路徑添加進該環境變量

我們也可以將自己的程序的路徑添加到該環境變量中。執行“export PATH=$PATH:程序路徑”即可將自己的程序添加進PATH環境變量

此時我們再執行自己的程序時,無需帶“./”就可以執行了:

注意,最好不要執行“export PATH=程序路徑”,該命令會將環境變量中的路徑覆蓋,而非添加路徑。執行后我們linux系統下的很多指令就會無法使用

當然,就算執行了也關系,因為該環境變量是一個“內存級”的環境變量,我們重登linux賬戶該環境變量就會恢復成原來的內容

當然,系統中還有許多環境變量,這里的PATH環境變量只是用來舉個例子,讓大家認識一下環境變量。其他的還有如“USER”環境變量用于識別用戶身份“HOME”環境變量用于表示用戶家目錄“PWD”環境變量記錄用戶當前所在路徑等等

2.添加環境變量

(1)添加本地變量

本地變量,就是指只在本地shell存在的變量。簡單來講,就是我們定義的本地變量只能在自己的進程中使用,無法被進程繼承。而環境變量,則是在該linux機器下的所有進程中都可以生效,會被進程繼承

如果我們想添加一個本地變量,可以在命令行上輸入“變量名="內容”(雙引號可帶可不帶,但建議帶上,避免你的變量中有空格等字符導致系統識別錯誤):

可以看到,通過這種方式,我們就可以直接定義一個本地變量。但是這僅僅是一個本地變量,如果我們用“env”這種搜索環境變量的命令是搜索不到的:

該指令沒有搜索到對應的環境變量

然后再來寫一個程序測試一下:

其中的myenv()函數會識別環境變量,如果該環境變量存在,就返回它的內容,否則就返回NULL

現在運行該程序:

此時輸出找不到該環境變量,這也說明了我們此時定義的僅僅是本地變量而非環境變量?

1.本地變量轉環境變量

如果我們想將本地變量改成環境變量,直接輸入“export 本地變量名”即可:

此時我們就可以搜到該本地變量了

3.取消環境變量和本地變量

如果我們不想要某個環境變量或本地變量,想取消掉,直接輸入“unset 變量名”即可:

?4.查看環境變量內容

(1)查看環境變量

如果想查看當前系統中的環境變量,直接輸入“env”命令即可:

這里并沒有截全,實際上在下面還有很多環境變量

如果你想查看單個環境變量的內容,就可以輸入“echo $環境變量”來查看指定的環境變量內容:

該環境變量中說明了我們命令行中上下翻動可記錄的最多的命令個數。如果你想看你歷史上使用過的命令,輸入“history”命令即可查看:

(2)查看本地變量和環境變量

如果我們還想看系統中的本地變量和環境變量,就可以輸入“set”命令。假設我們現在有一個“MYENV”本地變量,用“env”命令是搜索不到的。此時我們用“set”來搜索:

5.windows下的環境變量

其實不止linux有環境變量,windows也是有環境變量的

我們右擊電腦上的“此電腦”圖標,選擇屬性,點進去就可以看到有“高級系統設置”選項:

點進去后我們就可以看到“環境變量”選項:

點進“環境變量”選項就可以看見我們的電腦上的環境變量:

注意,如果沒有相關知識和技能,千萬不要嘗試修改或刪除這里的內容

6.int main()主函數中的參數

(1)int argc和char* argv[]

很多人可能不知道,我們每次寫代碼是的主函數int main()中其實是有參數的。其中一共有三個參數。我們先來介紹其中的前兩個參數

之前也說過,linux下的命令其實就是程序。但是,這些命令大家在使用過程中可以知道,是可以帶其他選項的。如“ls -l”、“ls -a”等等。既然這些程序都可以帶選項,那么按道理來講,我們自己寫的程序也是可以帶選項的

因此,我們先寫下面一個程序來看看參數“char*argv[]”中有什么:

我們執行該程序后可以看到打印了如下內容:

?argv[0]上的內容就是我們剛才執行的命令。此時我們在帶上幾個選項來運行該程序:

可以看到,此時argv[]中就是我們輸入的命令行中的參數。那此時“int argc”“char* argv[]”的作用就很明顯了。argc是用來表明命令中參數的數量的,而argv則是用來存儲參數的。在此時我們的輸入在命令行的內容如“./myprocess -a -b -c”被看做是字符串,當進入主函數后,這個字符串被分割為“./myprocess”“-a”“-b”“-c”一個個小字符串

既然argv中保存了選項,那我們再修改下程序:

此時我們執行該程序并帶上對應的選項:

可以看到,該程序成功的幫我們把對應的內容打印出來了。這也就進一步的說明了,其實linux中的命令就是用C語言寫的程序,并且我們自己寫的程序也是可以帶上選項執行對應功能的,只是我們以前沒有場景使用罷了

(2)char* env[]

對于這個參數,我們從名字上來看就很眼熟,因為查看環境變量的命令就是“env”。那么我們可以推測該參數是不是和環境變量有關。

我們寫以下一個程序來測試一下:

這里因為env[]沒有標識其內容個數的變量,因此直接用的是"env[i]"當判斷條件。但是這是因為env[]的最后一個字符默認指向“NULL”才能這樣用

?我們現在來運行一下程序:

其結果我們也很眼熟,我們再執行“env”查看環境變量:

它們的內容一模一樣。這也就說明了,主函數中的“env[]”是用來存儲環境變量的

因此,每個進程都會收到一份環境表,環境表是一個字符指針數組,每個指針指向一個以'‘\0’結尾的環境字符串。同時存儲這些環境變量的是char*數組。這就是為什么我們說“環境變量其實就是字符串”

五、進程地址空間

1.C/C++地址空間

在了解進程地址空間之前,我們先來回顧下C/C++的地址空間。大家應該都知道,C和C++的地址空間被分為代碼區、堆區、棧區等多個區域:

在堆區和棧區之間是有一個公共空間的,供雙方使用

當時我們可能以為這些地址空間就是內存上的內存。但是實際上它們并不是內存。在了解它們就是是什么之前,我們先來寫一個以下內容的程序:

該程序會創建一個子進程,并根據I變量“id”的返回值執行不同的操作。同時這里面定義了一個全局變量“global_value”,該變量在3s后會被子進程修改為300。并且父子進程選項中會打印其自己的pid、ppid和全局變量“global_value”的值及其地址

現在我們來執行該程序:

根據打印內容我們可以發現,在3s之前,父子進程打印的全局變量的值和地址都是相同的。這很正常。但是當3s后子進程將全局變量修改后,我們發現子進程打印的值變成了300,但是父進程打印的值依然是100。并且更其奇怪的是,此時父子進程打印的全局變量的地址竟然是一樣

我們之前說過,同一個地址上是不能同時存在不同的值的。但此時在同一個地址上卻出現了不同的值。這就說明,此時我們打印出來的地址并不是內存上真正的空間地址,而是“虛擬地址”。我們以前學習C/C++語言時打印的所有地址其實都不是內存上的物理地址,而是虛擬地址。“虛擬地址”也被叫做“線性地址”“邏輯地址”

而我們以前所說的C/C++地址空間其實就是“虛擬地址空間”。虛擬地址空間的存在也使我們更好的支持了并發

2.虛擬地址空間

(1)進程認為自身獨占系統資源

現在我們知道了在內存中存在虛擬地址空間。在理解虛擬地址空間之前,我們要先知道一個概念,“進程會認為它獨占系統資源”。當然,在實際上進程并沒有獨占系統資源

舉個例子,假如現在有一個有錢人,身價上百億。而他自己比較喜歡花天酒地,在外面有三個私生子。這三個私生子之間互不認識。有一天這個有錢人分別對他的三個兒子說,“你好好學習好好工作,等我去世以后就把遺產全部給你”。此時它的三個都非常高興,因為此時他們都認為自己會繼承父親的所有遺產。于是這三個兒子需要用錢時都會向付錢要錢。雖然他們知道自己將來能繼承全部遺產,但現在還沒有繼承,所以不會無限度的要錢。而父親為了不讓他們亂花錢,就設置了一個限度,超過這個限度就不會給他們錢。

在這個例子里面,三個兒子就好比是“進程”有錢人就好比是“內存”。三個兒子都認為自己會繼承全部遺產就好比是“進程認為自己獨占內存所有資源”兒子向父親要錢就是“進程向內存申請空間”父親設置的給錢的額度就是“內存給進程設置的申請空間的最大值”。而父親給三個兒子畫的繼承遺產的大餅就是“進程地址空間”

因此簡單來講,進程地址空間就是“操作系統給進程畫的大餅”

(2)系統如何使進程認為自己獨占所有資源

既然操作系統要讓進程誤認為自己獨占所有系統資源,那肯定要有一個方法。我們之前講過操作系統的管理方式是“先描述,再組織”,并且也了解了“PCB進程結構體”。而操作系統誤導進程的方法也是相似的。在操作系統中,會構建一個struct結構體,該結構體中就包含了操作系統對進程畫的餅的所有內容。

同時在系統中有幾十上百個進程,操作系統為了避免遺忘或弄錯給進程畫的餅,就會在每個進程中都放入一個結構體,用該結構體來記憶操作系統給進程畫的餅

因此進程地址空間的本質就是“是內核的一種數據結構,叫做mm_struct”

3.虛擬地址

在之前我們說進程地址空間的本質是“內核的一種叫做mm_struct的數據結構體”。既然是數據結構體體,那肯定就有結構體成員

在以前的學習中,想必大家都知道,地址空間描述的基本空間大小是字節。即一個地址代表一個字節

我們今天以32位系統來舉例,假設我們現在有一個32位的系統,那么在這個系統下, 就會有2^32次方個地址。而一個地址代表一個字節,就說明在32位的系統下有4GB的空間。而這2^32次方個地址就是用unsigned int類型來表示的。因為該類型所占空間大小為4字節,共32個bit位,就能夠保證2^32個地址都有唯一性

同時要注意,在系統中地址是從低地址向高地址使用的

(1)進程地址空間的區域劃分

1.區域劃分

我們說過在內存中劃分有堆區和棧區。但是我們并不了解堆區和棧區是如何劃分的。在這里,就舉一個例子來理解堆區與棧區的劃分

假設今天有小李和小王兩個人是同桌,他們之間經常玩鬧,有一天小李把小王惹生氣了,于是小王和小李絕交并拿起了筆,在桌子上畫了一條線,說這就是他們之間的“三八線”,各自用各自的區域不準越界。小李此時這種在雙方之間劃分使用區域的方式就叫做“區域劃分”

2.區域調整

當小李和小王過了一段時間后,小李安耐不住想和小王玩,但又苦于這條三八線,于是找小王提建議說能不能在中間劃分一個公共區域,大家就在這個公共區域玩。小王此時也沒有那么生氣了,也想和小李玩,就答應了小李的請求。于是小王拿起筆,在雙方直接劃了一個公共區域,之前是小李小王各50cm,現在就改成小李小王各45cm,中間的10cm作為他們兩個之間的公共玩耍區域。此時這種劃分公共區域的方法就叫做“區域調整”

3.區域擴大

小李和小王和好一段時間后,小李逐漸得意忘形,有一天又把小王惹生氣了, 并且比第一次還嚴重。于是小王此時怒不可遏,又拿出尺子來劃分“三八線”。這次小王就沒有再用評分的原則,而是直接縮減小李的空間,改成小李30cm,自己70cm。這種擴大自己空間的方式就叫做“空間擴大”

在系統中,要實現對空間的劃分,同樣會形成一個結構體。我們假設這個結構體叫做“struct Destop”,那么該結構體內就是保存了各個空間的起始地址和結束地址

由此,我們的地址空間也是用同樣的方法進行了劃分。在32位系統的進程地址空間中有4GB空間,這些空間就大致如下劃分:

?當然,這里并沒有全部寫完, 只是寫了部分區域劃分

(2)虛擬地址

現在我們知道了在系統中有一個叫“struct mm_struct”的內核結構體。那么進程在運行時,就會需要依靠這個結構體來生成一份進程地址空間。假設我們現在有一個進程,該進程的PCB結構體“task_struct”中有一個“mm”指針,該指針指向一塊malloc出來的“struct mm_struct”類型的空間:

而這塊空間中,當然要有對應的區域劃分,我們假設區域是如下方式劃分的:

在這里面的如0x1111 1111到0x1222 2222這種區域劃分出來的地址就叫做“區域起始地址”“區域結束地址”,而這些地址全部都是“虛擬地址”。并且這些虛擬地址的數量一定要是2^32

也就是說,我們的進程中都有一塊虛擬空間,這些虛擬空間中全部都是虛擬地址,而這些虛擬地址就是給我們的代碼、數據、堆區、棧區等各個空間使用的。要注意的是,如代碼區、數據區這些區域的大小是固定不變的。但是棧區和堆區的大小是會改變的。而結合上面所說的,堆區和棧區等的空間變化其本質上就是修改結構體中對應區域的起始地址和結束地址

而我們之前說的操作系統會進程畫餅,讓操作系統誤以為自己獨占所有資源。這個餅其實就是我們上面的mm,即我們的虛擬地址空間

4.頁表

雖然進程中用的是虛擬進程空間和虛擬地址,但是進程最終還是需要存在內存中,使用物理地址的。要使用物理地址,就需要用虛擬地址找到物理地址,而虛擬地址找到物理地址的媒介,其實就是頁表

假設現在我們有一個磁盤,在這個磁盤中有一個test.exe程序,該程序加載到內存中要占用1k字節的空間。這個進程的在進入內存時,會對應生成一個“PCB結構體”,該結構體中的mm指針指向一塊malloc出來的進程地址空間。假設此時這個進程想要定義一個char ch = 1,需要一個字節的空間。此時該空間會先有一個虛擬地址,然后再通過頁表,將虛擬地址映射到物理地址上,此時才完成了定義

當然,實際的頁表并不是一個虛擬地址對應一個物理地址。因為我們假設一個地址占四個字節,找一次地址就要2個地址,也就是8個字節。而32位系統下一共有2^32個地址,再乘以8,就需要32GB空間,這樣僅僅一個頁表就比內存都大了。使用在系統中的頁表實際是非常復雜的,采用了樹狀結構來減少空間使用。此處只是為了方便認識頁表才這樣畫?

注意,頁表每個進程都有的,而非在系統只有一個頁表:

5.虛擬地址空間存在原因

有人可能認為,直接讓進程訪問物理地址而不是從虛擬地址通過頁表映射到物理地址上會更加方便。誠然,這樣確實更方便,但是也會存在一定問題

(1)保護其他進程和用戶信息

首先虛擬地址空間就是為了保護其他進程和用戶信息。假設我們現在沒有虛擬地址空間,進程可以直接訪問物理內存。如果該進程中存在越界訪問的問題,并且這個進程的旁邊是另一個進程的數據,此時就會導致其他進程的數據有遭到修改的風險

同時,如果你的電腦上有一個惡意程序,該程序運行起來直接就訪問了你的物理內存,而你的物理內存上存在許多信息,包括你的各類用戶信息。那么此時該進程就可以隨意訪問你的信息,并將其返回到程序中供他人非法獲取

有人就很奇怪了, 雖然進程是通過虛擬地址找到物理地址的,但最終還是要到物理地址上去,那虛擬地址如何保護我們的數據呢?其實這一保護功能不是由虛擬地址完成,而是由“頁表”完成。不要簡單的認為頁表只能提供映射,其實它還存在許多其他功能,就包括對進程行為的識別

舉個例子,我們小時候都得到過壓歲錢,這些壓歲錢在我們手里,我們可以直接用,想買什么買什么。但是這個時候我們的父母通常會過來,告訴我們說把壓歲錢交給他們保管。我們上交之后,每次想買點零食時,父母都會從我們的壓歲錢里面拿點出來給我們。有一天,我們想買本漫畫書,找父母要錢,此時他們就以妨礙學習為由,不給我們錢。

在這里面,我們就是進程,父母就是頁表。父母把壓歲錢收管,根據我們的需求來決定是否給我們錢就是頁表在對進程的行為進行識別,判斷是否合法

(2)保證進程的獨立性

我們之前寫過這樣一個程序:

該程序重復打印子進程和父進程的pid、ppid和一個全局變量"global_value"的值。并且子進程會在3s后修改global_value的值

雖然全局變量“global_value”的值被改變了,但是在父子進程打印的全局變量的地址并沒有改變的情況下,父子進程打印的gobal_value的值卻不同。導致這個結果的原因就是“進程具有獨立性”

在內存中,每個進程都有其獨立的內核數據結構,父子進程也不例外:

?我們說了父子進程因為其代碼都是相同的,因此是“共享代碼”的。也就是說,這兩個進程在全局變量"gobal_value"未被修改時父子進程通過虛擬地址找到的都是同一塊空間上的同一個值

但是在過了3s后,此時子進程會修改“gobal_value”的值,如果修改原空間上的值,勢必會導致父進程的值也會被修改。就無法保證父子進程的獨立性

因此某一個進程要對共享代碼中的數據進行修改時,會先將原內存中的內容拷貝一份,然后在物理內存中重新找一塊空間將內容拷貝進去。再修改頁表將對應虛擬地址映射到物理地址,然后再修改這塊空間上的值

這種任何一方嘗試寫入或修改數據,?操作系統先進行數據拷貝,更改頁表映射然后再讓程序進行修改行為,叫做“寫時拷貝”。父子進程就是通過“寫時拷貝”的方式來實現不同進程的數據分離。這是由操作系統來幫我們做的

對于那種毫不相干的進程,他們之間的內核數據結構和進程對應的代碼和數據都是獨立的,這也就保證了數據之間的獨立性

因此,地址空間的存在,可以更方便的進行進程和進程的數據代碼的解耦,保證進程之間的獨立性

(3)便于編譯器以統一視角編譯代碼

我們一直說每個程序加載到內存中會有一個PCB結構體,里面保存了關于該進程的各類屬性和代碼數據地址。但是,不僅僅是程序加載到內存中會有一塊虛擬地址空間保存虛擬地址,程序在加載到內存之前也是有地址的。這個地址也是虛擬地址,不過我們通常叫做邏輯地址

很簡單的一個道理,我們自己寫的程序,在我們編譯運行時我們說了,函數調用時要通過函數的地址去找到對應的函數聲明,而這里的函數地址并不是加載到內存中才有的,而是在我們代碼進行編譯的時候就有了。換句話說,我們的程序在進入內存變成進程之前它的內部就已經有一套虛擬地址了。這套虛擬地址和進程結構體中的虛擬進程空間采用同樣的方式,都是有2^32個地址

舉個例子。假設我們現在有一個my.exe程序,這個程序的代碼如下圖所示:

當我們寫好這個程序,將該程序進行編譯時,該程序的內部就會自動為每個函數、每行代碼乃至每個變量都生成一個虛擬地址,并且里面調用了函數或者使用了其他變量的代碼的地址就是其對應的定義處的地址:

當我們的程序運行起來加載到內存里面時,該進程本身就又有了一套地址。注意這里該進程其實有兩套地址,一套是進程內部進行跳轉的虛擬地址,另一套是標識該進程在物理內存中存在的物理地址

此時我們要意識到,當程序加載進內存時,會形成一個PCB結構體,這個結構體中有一個mm指針指向開辟的進程地址空間,該地址空間中會用多個start、end值來標識各個區域的空間劃分。我們以代碼段為例,上述程序中的代碼都需要保存在代碼區中,而代碼區的大小就是主函數的代碼大小,我們圖中的主函數是從0x1111 1111開始的,我們假設該代碼的大小是10kb,那么代碼區的結束位置就是“0x1111 1111?+ 10kb”。

有了這些準備后我們再來進程與CPU的尋址問題。這里要記住,加載到CPU中的是進程的PCB結構體,而非進程本身。假設該程序此時運行到主函數中的func()函數調用處,此時系統就會將func()函數的虛擬地址0x1122 2222加載到CPU中,CPU再通過該地址找到該進程的進程地址空間的對應位置,然后通過進程地址空間與頁表的映射找到物理內存中的代碼存儲位置,然后去調用func()函數。func()中的a變量也是同理。要調用a變量,就要將a變量的虛擬地址加載到CPU中,CPU通過該地址找到該進程中的進程地址空間中的a變量的位置,通過這個地址與頁表映射找到物理內存中a的物理地址進行調用

在這整個過程中,CPU都知道對應代碼的虛擬地址,并沒有見到過它的物理地址。而程序中自行形成的虛擬地址的格式與地址位置和進程中的進程結構體指向的進程地址空間是差不多的。也就是說,程序中的虛擬地址與進程地址空間的虛擬地址在一般情況下是一樣的。這樣也就便于CPU直接將對應虛擬地址放到進程地址空間去進行頁表映射?

因此,進程地址空間存在的另一個重要原因就是“讓進程以同一的視角,來看待進程對應的代碼和數據等各個區域,方便使用。同時也讓編譯器以統一的視角來編譯代碼。”這樣,代碼編譯完后,就可以直接使用了

5.線性地址與邏輯地址

(1)線性地址

我們之前說,虛擬地址又叫做線性地址。因為虛擬地址是從0一直到2^32,是連續不斷的。因此在一些教材里面,虛擬地址又被叫做“線性地址”

(2)邏輯地址

邏輯地址其實就是在程序內部的用于代碼跳轉的地址。只不過在linux中我們說的邏輯地址和虛擬地址是一個東西。但是虛擬地址的名字聽起來更好理解,所以在文中用的都是虛擬地址,但是在實際中常用的名字是邏輯地址

總結

以上是生活随笔為你收集整理的初识linux之进程的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

精品国产免费一区二区三区五区 | 国产一区高清在线 | 久久国产91 | 日韩免费精品 | 麻豆视频在线免费 | 婷婷综合五月 | 黄色免费网 | 天天综合网入口 | www.五月天婷婷.com | 亚洲国产中文字幕 | 日韩av在线网站 | 亚洲欧美久久 | 黄色特级一级片 | 欧美乱码精品一区二区 | 91精品国产一区 | 国产高清精品在线 | 精品福利片 | 日韩免费一区二区三区 | 日韩精品欧美专区 | 午夜在线日韩 | 欧美va天堂在线电影 | 中文字幕亚洲在线观看 | 久久久久久久久久久电影 | 免费观看性生活大片3 | 国产精品高清免费在线观看 | 狠狠操精品 | 国产亚洲精品久久久久久久久久久久 | 国产精品一区二区三区在线看 | 中文字幕亚洲五码 | 国产黄色精品在线观看 | wwxxx日本| 国产亚洲视频在线免费观看 | 不卡电影免费在线播放一区 | 国产精品自在欧美一区 | 久久精品久久精品久久 | 亚洲一二区视频 | 日韩成人精品 | av一级片网站 | 一区二区三区久久 | 欧美久久久久久久 | 久久伦理 | 91精品一区二区在线观看 | 黄色网址国产 | 国产高清成人av | 精品国偷自产国产一区 | www久| 国产成人99久久亚洲综合精品 | 最新av免费 | 视频在线一区二区三区 | 激情综合亚洲 | 欧美一区二区三区在线看 | 五月天高清欧美mv | 91av蜜桃 | 玖玖爱国产在线 | 国产精品18久久久 | 国产 一区二区三区 在线 | 国产一区二区免费在线观看 | 四虎影视欧美 | 欧美韩国日本在线 | 特级毛片在线观看 | 偷拍精偷拍精品欧洲亚洲网站 | 国产黄色精品视频 | 最近最新中文字幕视频 | 夜夜婷婷 | 久久se视频 | 91理论电影 | 日日麻批40分钟视频免费观看 | 999久久久久久久久 69av视频在线观看 | 99久久精品免费看国产免费软件 | 国产中文视 | 久久一区二区三区日韩 | 国语精品久久 | 在线视频 国产 日韩 | 制服丝袜欧美 | 亚洲精品中文在线 | 特级西西人体444是什么意思 | 九月婷婷综合网 | 免费一级片久久 | 久久精品久久精品久久39 | 亚洲精选在线 | 久久国产精品一区二区三区 | 天天射成人 | 国产一区二区三区高清播放 | 四虎在线免费视频 | 三级性生活视频 | 中文字幕在线免费观看视频 | 永久免费av在线播放 | 亚洲国产日韩欧美 | 国产又粗又猛又爽 | 亚洲精品1区2区3区 超碰成人网 | 日韩黄色在线电影 | 国产精品一区二区av日韩在线 | 97免费在线观看 | 亚州国产视频 | 插婷婷| 2021国产精品 | 国产精品va在线 | 97视频免费播放 | 天天射网站 | www色网站| 日本超碰在线 | 一级成人网| 亚洲精品久久久久久久蜜桃 | 婷婷综合导航 | 超碰夜夜 | 国产黄色精品在线观看 | 五月婷婷香蕉 | 日本精品久久久久中文字幕5 | 久久久影院一区二区三区 | 成人av中文字幕在线观看 | 国产精品国内免费一区二区三区 | 草久电影 | 91天天操 | 久久久亚洲影院 | 日韩色综合网 | 亚洲视频1 | 国产精品日韩欧美一区二区 | 免费在线观看国产精品 | 欧美-第1页-屁屁影院 | 午夜精品久久久久久99热明星 | 久久国产精品久久久久 | 四虎永久网站 | 黄网站色 | 国产精品手机视频 | 手机在线免费av | 亚洲国产免费看 | 欧美日韩观看 | 久久在线免费视频 | 日韩小视频网站 | 成人免费观看视频大全 | 欧美日韩国产免费视频 | 国产精品免费av | 欧美小视频在线观看 | 久操视频在线观看 | 久艹视频免费观看 | 三级动态视频在线观看 | 国产第一福利 | 99久久99久久精品免费 | 激情欧美一区二区三区免费看 | 夜夜天天干 | 欧美性大胆 | 精品在线观看一区二区 | www.com黄色 | 久久久91精品国产一区二区三区 | av黄色av | 久久首页| 国产精品乱码久久久 | 视频成人永久免费视频 | 亚洲国产免费网站 | 99热99| 在线观看自拍 | 成人av免费在线播放 | 精品在线亚洲视频 | 久久视频这里有久久精品视频11 | 中字幕视频在线永久在线观看免费 | 久久99日韩| 免费黄a | 99久久精品免费看国产免费软件 | 亚洲天堂自拍视频 | 99九九热只有国产精品 | 最近最新最好看中文视频 | 亚洲一二三久久 | 国产一二三精品 | 精品在线观看国产 | 91精品国产99久久久久久久 | 日韩中文在线字幕 | 国产99视频在线观看 | 国产精品久久久久久爽爽爽 | 日韩一区二区三区免费视频 | 玖玖在线精品 | 精品99免费视频 | 97精品国产 | 日韩精品久久久久久 | 欧美一级片 | 98久9在线 | 免费 | 一区二区三区在线观看免费视频 | 精品国产乱码久久久久久三级人 | 香蕉视频亚洲 | 免费男女羞羞的视频网站中文字幕 | 99久久国产免费,99久久国产免费大片 | 天天夜夜操 | 亚洲另类视频在线观看 | 国产成人av电影在线观看 | 激情五月婷婷综合网 | 国产一线二线三线性视频 | 亚洲黄色成人网 | 国产成人久久精品77777综合 | 亚洲国产成人精品在线观看 | 久久国产手机看片 | zzijzzij日本成熟少妇 | 国产精品高潮呻吟久久久久 | 夜夜骑天天操 | 成人a级免费视频 | 亚洲成人影音 | 狠狠色丁香久久婷婷综合_中 | 亚洲综合视频在线 | 国产一级淫片在线观看 | 日韩视频一二三区 | 国产高清精 | 国产成人久久精品77777 | 亚洲乱码国产乱码精品天美传媒 | 悠悠av资源片 | 婷婷丁香狠狠爱 | 婷婷六月天丁香 | 日本午夜在线观看 | 亚洲免费一级 | 国产精品福利在线播放 | 日躁夜躁狠狠躁2001 | 中文超碰字幕 | 9797在线看片亚洲精品 | 亚洲日本一区二区在线 | 在线观看视频在线 | a视频在线| 国产一区二区中文字幕 | 亚洲永久精品在线 | 免费a v在线 | 小草av在线播放 | 最新国产福利 | 国产成人综 | 91免费看片黄 | 精品一区二区日韩 | 久久人91精品久久久久久不卡 | 色播五月激情五月 | 五月情婷婷 | 欧美激情综合五月色丁香 | 激情网在线视频 | 亚洲视频999 | 欧美一区二区三区激情视频 | 国产精品久久久区三区天天噜 | 狠狠干狠狠操 | 亚洲精品国产精品国自 | 首页av在线| 亚洲mv大片欧洲mv大片免费 | 日韩在线电影观看 | 免费网站在线观看人 | 国产精品99久久久久人中文网介绍 | 国产精品久久久久永久免费观看 | 国产精品久久久久久久久岛 | 欧美激情综合五月色丁香小说 | 超碰av在线播放 | 91精品国产成人www | 久久国产精品99久久久久 | 日韩视频a| 国产一区二区三精品久久久无广告 | 91av在线免费视频 | 亚洲国产三级在线 | 日韩精品视频在线观看免费 | 亚洲精品国精品久久99热一 | 精品人人爽| 91精品免费 | 国产成人精品一区二区三区福利 | 六月丁香在线观看 | 日日摸日日添日日躁av | 国产黄色大全 | 精品一二三区 | 日本3级在线观看 | 日韩在线观看视频中文字幕 | 久久黄色小说 | 日韩av电影中文字幕 | 少妇bbb | 国产一区欧美在线 | 久久精品观看 | 99在线热播 | 一区二区欧美在线观看 | 中文字幕成人在线观看 | 日韩一区二区三区高清免费看看 | 精品视频在线播放 | 国产精品九九久久99视频 | 婷婷av网 | 亚洲成人国产精品 | 伊人网综合在线观看 | 亚洲色图 校园春色 | 色综合久久88色综合天天 | 美女久久久久 | 国产欧美综合在线观看 | 日韩av网站在线播放 | 六月丁香激情综合 | 狠狠干夜夜操 | 免费黄色小网站 | 中文字幕在线观看1 | 国产精品亚洲综合久久 | 免费在线91 | 日本中文在线播放 | 丝袜美女视频网站 | 不卡国产在线 | 日韩免费一级a毛片在线播放一级 | 久久在草 | 99精品欧美一区二区蜜桃免费 | 久久久人人爽 | av在线免费播放 | 日本黄色免费大片 | 欧美综合在线观看 | 久久精品香蕉视频 | 9999免费视频 | 在线观看中文字幕av | 99久久电影| 国产一区在线播放 | 亚洲国产电影在线观看 | 一区二区三区电影在线播 | 看全黄大色黄大片 | 欧美在线观看视频 | 色综合天天天天做夜夜夜夜做 | 精品国产理论 | 精品中文字幕在线观看 | 国产精品 中文字幕 亚洲 欧美 | 91成人精品一区在线播放 | av免费电影在线观看 | 日本精品中文字幕在线观看 | 欧美人人 | 亚洲在线视频网站 | 亚洲午夜av久久乱码 | 日韩欧美高清视频在线观看 | 久久亚洲人 | 91超碰免费在线 | 日本性生活一级片 | 99久久这里只有精品 | 日韩网站中文字幕 | 毛片网站免费在线观看 | 黄色一及电影 | 欧美色图亚洲图片 | 免费看v片网站 | 久久综合中文色婷婷 | 日韩欧美区 | 在线观看韩国av | 国产视频一区二区在线观看 | 五月婷婷深开心 | 久久人人爽人人 | 91免费网 | 韩国精品在线 | 久草免费资源 | 久久久久国产一区二区三区 | 国产剧情一区二区 | 人人爽人人爱 | 久久视奸| 在线视频18在线视频4k | 麻豆视频网址 | 天天操天天色天天 | 五月花丁香婷婷 | 精品一区在线看 | 91视频-88av| 午夜视频在线观看一区 | 国产h在线观看 | 色吊丝av中文字幕 | 91香蕉国产在线观看软件 | 久草com | 97av在线视频 | 在线观看av大片 | 欧美性大胆 | 亚洲成av人片在线观看香蕉 | 久久大片网站 | 欧美最猛性xxxxx(亚洲精品) | 99精品黄色片免费大全 | 国产免费人成xvideos视频 | 中国一级片免费看 | 美女视频国产 | 中文亚洲欧美日韩 | 日韩免费福利 | 成人免费看电影 | 欧美最爽乱淫视频播放 | 国产精品区一区 | 色婷五月天 | 久久久久久久久久久网站 | 最近中文字幕免费视频 | 手机在线观看国产精品 | 黄色三级av | 日日夜夜综合 | 亚洲成人xxx | www.黄色小说.com | 欧美在线观看小视频 | 亚洲免费在线观看视频 | 国产中文字幕一区二区 | 日韩电影中文字幕在线 | 日韩免 | 九色视频自拍 | 91毛片在线| 一区二区三区国产欧美 | 久久久综合香蕉尹人综合网 | 激情久久婷婷 | 国产真实在线 | av蜜桃在线 | 免费久久久久久久 | 六月激情网 | 中文字幕在线播放视频 | 丁香六月色 | 亚洲一级电影 | 狠狠干夜夜 | 草久视频在线观看 | 成年人av在线播放 | 亚洲黄色免费在线看 | 黄色网中文字幕 | 日韩在线视频观看免费 | 亚洲九九九在线观看 | 久久成人在线视频 | 亚洲春色奇米影视 | 精品高清视频 | 亚洲久草在线 | 久久五月天综合 | 狠狠色综合欧美激情 | 国产精品久久久久久模特 | 99999精品 | 成人小视频在线 | 国产直播av | 少妇视频在线播放 | 国产一卡二卡四卡国 | 免费在线91| 日本久久片| 成年人毛片在线观看 | 亚洲资源网| 99色国产 | 成人国产精品久久久久久亚洲 | 日韩精品一区二区电影 | 国产亚洲精品中文字幕 | 免费久草视频 | 中文字幕成人在线观看 | 久久草av| 精品国产欧美一区二区三区不卡 | 69精品久久久| 日韩v在线91成人自拍 | 在线免费精品视频 | 成人精品久久久 | 中文网丁香综合网 | 亚洲视频 视频在线 | 国产一级在线看 | 亚洲综合丁香 | 婷婷亚洲五月 | 国产国语在线 | av一级网站 | 在线观看国产一区二区 | 天天色影院 | 中文字幕av全部资源www中文字幕在线观看 | 91色欧美 | 99中文视频在线 | 全黄网站| 一区二区三区在线不卡 | 91成人观看 | 久久99精品久久久久婷婷 | 中文字幕 婷婷 | 天天曰夜夜爽 | 欧美综合干 | 日韩在线观看第一页 | 亚洲精品美女免费 | 国产精品一区二区无线 | 成人h在线观看 | 国产午夜一区 | 国产网红在线 | 中文字幕 影院 | av高清影院 | 中文字幕在线视频第一页 | 一区av在线播放 | 射九九 | 欧美另类网站 | 国产精品一区欧美 | 69xx视频| 成人午夜电影在线观看 | 婷婷网站天天婷婷网站 | 国产精品国产三级国产不产一地 | 婷婷伊人五月 | 91av电影在线 | 99免在线观看免费视频高清 | 天天综合五月天 | 一区二区三区三区在线 | 午夜国产一区二区三区四区 | 久久免费看片 | 三上悠亚一区二区在线观看 | 精品久久久成人 | 日韩av黄 | 午夜精品一二区 | 在线观看一级 | 色欲综合视频天天天 | 在线三级播放 | 久久午夜电影院 | 中文字幕亚洲综合久久五月天色无吗'' | 最新av电影网址 | 免费a网 | 美女网站视频免费都是黄 | 人人爽人人澡 | 精品久久久久久一区二区里番 | 激情婷婷丁香 | 久久99国产一区二区三区 | 欧美欧美| 99国产成+人+综合+亚洲 欧美 | 97超在线视频 | 国产区精品区 | 久久精品视频中文字幕 | 99久高清在线观看视频99精品热在线观看视频 | 超碰在线天天 | 黄网站免费大全入口 | 国产精品久久久久一区二区国产 | 日本中文字幕在线视频 | 国产精品免费视频网站 | 日日操日日 | 亚洲精品高清在线 | 国产精品毛片久久久久久久久久99999999 | 91麻豆精品国产91久久久更新时间 | 亚洲成人精品久久久 | 久久公开视频 | 日韩欧美精品一区二区 | 欧美性久久久 | 亚洲闷骚少妇在线观看网站 | 久久国精品| 久久人人做 | 色偷偷人人澡久久超碰69 | 国产韩国日本高清视频 | 国产精品igao视频网入口 | 成年人在线看片 | 92国产精品久久久久首页 | 欧美a级在线 | 亚洲日韩中文字幕在线播放 | 三级大片网站 | 91高清免费观看 | 色综合色综合色综合 | 一级特黄aaa大片在线观看 | 国产精品精品久久久 | 伊人久久国产精品 | 欧美成人h版| 亚洲成人午夜av | 久草在线视频网 | 中文字幕在线观看国产 | 久久区二区 | 91亚洲网站 | 亚洲一区二区精品视频 | 色香网| 日韩色一区二区三区 | 国产手机av | 中文字幕久久网 | 黄色国产高清 | 久草在线在线视频 | 国产视频在| 中文字幕在线播放一区二区 | 午夜视频亚洲 | 亚洲 中文 欧美 日韩vr 在线 | 久久99视频免费观看 | 在线观看久草 | 国产亚洲精品中文字幕 | 日本aa在线| 久久99精品国产麻豆婷婷 | 久久热首页 | 成人黄色在线观看视频 | 天天玩天天操天天射 | 欧美日韩在线观看一区二区三区 | 日韩免费一级a毛片在线播放一级 | 中文字幕中文中文字幕 | 中文字幕中文字幕中文字幕 | 久艹在线免费观看 | 91九色在线观看 | 亚欧日韩成人h片 | 免费看三级黄色片 | 国产午夜麻豆影院在线观看 | 国产亚洲欧美精品久久久久久 | 成片免费观看视频大全 | 欧美日韩精品在线播放 | 国产91精品看黄网站 | 国产精品亚| 午夜影院日本 | 美女黄色网在线播放 | 亚洲精品伦理在线 | 久久精品国产一区二区三 | 成人精品99 | 亚洲精品久久久久中文字幕m男 | 狠狠色伊人亚洲综合成人 | 欧美日本一区 | 国产黄色免费 | 99热精品国产一区二区在线观看 | 亚洲精品美女在线观看播放 | 久草在线91| 日韩av手机在线观看 | 久久久亚洲网站 | 精品中文字幕视频 | 国产精品6999成人免费视频 | 国产精品一区二区在线 | 国产成人精品久久久 | 亚洲天堂精品视频 | 高清有码中文字幕 | 天天做日日爱夜夜爽 | 狠狠色丁香婷婷综合久久片 | av色综合 | 午夜在线观看 | 成年人免费看av | 国产毛片在线 | 去干成人网 | 亚洲国产精品成人va在线观看 | 久久精品激情 | 国产一级免费播放 | 天天爽天天碰狠狠添 | 欧美人牲| 日韩精品免费在线 | 国产特级毛片aaaaaaa高清 | 午夜久久影院 | 久久久国产影院 | 久久神马影院 | 99久久婷婷国产综合精品 | 丁香婷婷综合激情五月色 | 欧美激情综合五月色丁香小说 | 美女网站色 | 在线观看你懂的网址 | 亚洲资源网 | 中中文字幕av| 综合网天天色 | 欧美少妇xxx | 视频高清| 国产专区在线看 | 日韩精品一区在线播放 | 欧美一级片在线观看视频 | 亚洲视频每日更新 | 99超碰在线播放 | 欧美性色网站 | 99久久精品日本一区二区免费 | 欧美一二区在线 | 日产av在线播放 | 中文 一区二区 | 99久久精品免费看国产 | 看黄色.com| 日韩av视屏在线观看 | 成年人黄色免费视频 | 久久视频在线视频 | 男女视频国产 | 日韩免费在线观看 | 乱男乱女www7788| 去干成人网 | bbb搡bbb爽爽爽 | av中文字幕在线免费观看 | 18国产精品白浆在线观看免费 | 奇米网网址| 日日爽 | 国产在线探花 | 97在线观看免费观看 | 婷婷去俺也去六月色 | 亚洲精品乱码久久久久久蜜桃91 | 日本中文字幕网站 | 中文字幕日韩国产 | 日日日干 | 高清av免费一区中文字幕 | 日韩成人黄色av | 婷婷色网 | 精品久久99 | 免费看污污视频的网站 | 精品一区二区精品 | 亚洲欧洲精品一区二区精品久久久 | 亚洲精品在线一区二区三区 | 91av视频免费在线观看 | 色香蕉网 | 激情综合狠狠 | 91麻豆精品国产91久久久更新时间 | 91麻豆文化传媒在线观看 | 久久资源总站 | 精品a视频 | 99这里只有久久精品视频 | 国产999精品久久久久久麻豆 | 中文字幕一区2区3区 | 国产91在线看 | 一本色道久久综合亚洲二区三区 | 国产一区在线精品 | 97精品超碰一区二区三区 | 亚洲国产一区在线观看 | 国产色爽| 免费看91的网站 | 在线免费观看黄色 | av在线8| 欧美久久久久久久久久 | 在线观看资源 | 亚洲国产精品va在线看 | 国产又黄又猛又粗 | 国产中文字幕视频在线观看 | 麻豆成人小视频 | 亚洲人av免费网站 | 日日干美女 | 成人性生交大片免费看中文网站 | 正在播放一区二区 | 欧美亚洲国产日韩 | 亚洲自拍自偷 | 91视频在线国产 | 久久国产精品一区二区 | 精品国产一区二区三区久久久 | 婷婷色中文 | 九九久久成人 | 日韩三区在线观看 | 天堂av网在线| 久久99精品久久久久久清纯直播 | 日韩av中文在线观看 | 99国产情侣在线播放 | 在线视频 区 | 2019中文在线观看 | 日韩欧美在线国产 | 久久国产精品视频免费看 | 久久久精品一区二区 | www.久久久.com | 国产女教师精品久久av | 精品久久综合 | 在线观看的av网站 | 91视频在线观看免费 | 国产视频观看 | 国产91丝袜在线播放动漫 | 热九九精品 | 国产精品久久久久久久av电影 | 欧美小视频在线观看 | 欧美日韩国产在线一区 | 日本乱码在线 | 激情丁香在线 | 精品一区电影 | 国产精品视频在线观看 | 爱爱av网站 | 天天操天天色综合 | 成人天堂网 | 色婷婷成人网 | 久久天天躁 | 久久国产欧美日韩精品 | 日韩在线视频网站 | 美女网站在线看 | 在线免费看片 | 最新av网址在线观看 | 97热在线观看 | 国产欧美久久久精品影院 | 久久免费视频一区 | 国产一二区视频 | 992tv又爽又黄的免费视频 | 久久99国产精品免费 | 久久久久激情电影 | 91大神一区二区三区 | 久久夜av | 久久激情视频 久久 | 亚洲 欧洲 国产 精品 | 亚洲精品一区二区三区新线路 | 国产无遮挡又黄又爽在线观看 | 精品亚洲二区 | 亚洲九九爱 | 中文字幕人成一区 | 日韩中字在线 | 中文字幕av在线电影 | 五月婷婷中文 | 精品福利视频在线 | 97色综合| 欧美性生爱 | 国产欧美三级 | 欧美日韩亚洲精品在线 | 欧美在线你懂的 | 亚洲视频免费在线观看 | 美女视频黄频大全免费 | 日韩av片无码一区二区不卡电影 | 国产大片黄色 | 98超碰在线 | 婷婷中文字幕在线观看 | 日韩免费视频在线观看 | www.天天成人国产电影 | 亚洲午夜精品久久久久久久久 | 91高清视频在线 | 久久久久中文 | 国产一及片 | 久久精品国产精品 | www.午夜视频| 亚洲国产精品激情在线观看 | 美国人与动物xxxx | 99精品久久只有精品 | 亚洲国产中文字幕在线视频综合 | 国产在线播放一区 | 国产精品www | 偷拍精偷拍精品欧洲亚洲网站 | 国产精品99爱| 久久久精品一区二区 | 91亚洲激情| 亚洲国产精彩中文乱码av | 亚洲专区一二三 | 99热手机在线观看 | 日韩一区二区免费视频 | 亚洲精品18日本一区app | 免费av高清 | 中文亚洲欧美日韩 | 人人舔人人射 | 成人国产精品久久久久久亚洲 | 欧美韩国日本在线 | 日日干夜夜干 | 久久久久久久久久免费 | 国产一区高清在线 | 日韩精品欧美专区 | 久久综合精品一区 | 91人网站 | 欧美一级电影在线观看 | 字幕网资源站中文字幕 | 6699私人影院 | 欧美成人一二区 | 青青河边草免费视频 | 99热最新 | 日本三级全黄少妇三2023 | 91精品夜夜 | 国产一级小视频 | 在线观看视频一区二区三区 | 久久久精品小视频 | 天天夜操 | 99视频网址| 欧美日韩一区久久 | 伊人开心激情 | 999久久久久久 | 狠狠色综合网站久久久久久久 | 国产资源在线观看 | 丁香六月国产 | 女女av在线 | 久久综合成人 | 欧美黄色特级片 | 亚洲理论电影网 | 欧美性色黄大片在线观看 | 亚洲麻豆精品 | 亚洲精品视频国产 | 久久久综合九色合综国产精品 | 日韩av网址在线 | 超碰人人在线观看 | 色狠狠综合 | 中文字幕免费在线 | 欧美精品一区二区免费 | 精品国产乱码久久久久久天美 | 91精品一 | 天天操天天舔天天爽 | 99精品视频一区二区 | 日日婷婷夜日日天干 | 国产精品美女久久久久久久 | 亚洲成人av电影在线 | 久久久久久看片 | 91视频国产免费 | 国产精品福利午夜在线观看 | 久草在线欧美 | 丁香六月五月婷婷 | 国产精品午夜在线观看 | 日韩av网站在线播放 | 91传媒在线看 | 久久精品久久精品久久精品 | 97偷拍视频 | 亚洲视频免费在线观看 | 精品国产1区 | 久久久国产成人 | 久久综合偷偷噜噜噜色 | 美女视频黄是免费的 | 久久精品永久免费 | 亚洲高清久久久 | 中文字幕在线观看第一页 | 免费看黄20分钟 | www黄免费 | 亚洲黄色区 | 99久久精品免费看 | 久久国产精品99久久久久 | 成人动漫视频在线 | 亚洲va韩国va欧美va精四季 | 又爽又黄又无遮挡网站动态图 | 97超碰在线免费观看 | 成av在线| 精品亚洲午夜久久久久91 | 国产精品专区一 | 久久久久国产成人免费精品免费 | 久草网视频 | 国产精品私人影院 | 综合色影院 | 亚洲天堂视频在线 | 亚洲男男gaygay无套 | 91视频在线观看下载 | 亚洲欧美va | 精品国产激情 | 久久r精品| 麻豆传媒视频在线免费观看 | 在线成人观看 | 日批视频在线观看免费 | 中文字幕在线观看网站 | 深爱激情av | 久草视频视频在线播放 | 色在线视频网 | 久久精品2 | 欧美性大战久久久久 | 伊人久久影视 | 国产综合香蕉五月婷在线 | 国产在线观看你懂的 | 国产福利精品一区二区 | 久久午夜电影院 | 天天综合视频在线观看 | a级国产乱理论片在线观看 特级毛片在线观看 | 久久蜜臀一区二区三区av | 日韩欧美高清在线观看 | 国产精品女同一区二区三区久久夜 | 亚洲免费av电影 | 超碰成人网 | 一区二区精品在线 | 欧美日韩国产在线观看 | 蜜臀久久99静品久久久久久 | 69国产成人综合久久精品欧美 | 国产精品乱码一区二区视频 | 中文字幕乱码一区二区 | 国产伦精品一区二区三区… | 久久免费精品视频 | 成人在线观看免费 | 97超碰在线资源 | 久久久久欠精品国产毛片国产毛生 | 欧美午夜一区二区福利视频 | 96亚洲精品久久 | 玖玖爱国产在线 | 麻豆精品视频在线 | 国产xxxx性hd极品 | 一级特黄av | 99精品视频一区二区 | 天天综合亚洲 | 午夜精品在线看 | 亚洲免费视频观看 | 日韩免费专区 | 亚洲日本一区二区在线 | 欧美日韩在线视频一区 | 久久久久久美女 | 国产精品成人a免费观看 | 91综合色| 亚洲艳情| 国产精品精品国产色婷婷 | 久久久久9999亚洲精品 | 91成人免费观看视频 | 81国产精品久久久久久久久久 | 日韩精品一区二区三区视频播放 | 狠狠操欧美 | 色婷婷福利| 成人av动漫在线观看 | 日韩色综合 | 日韩成人精品一区二区三区 | 九色91在线 | 99超碰在线观看 | 久久久首页 | 激情综合一区 | 成人综合婷婷国产精品久久免费 | 五月婷婷六月丁香激情 | 丁香激情视频 | 久久99久久99精品免费看小说 | 欧美成年网站 | 九九色综合 | 97人人网| 免费观看xxxx9999片 | 最新中文字幕在线资源 | 久久综合五月天婷婷伊人 | 久草| www.狠狠操| 免费av网址大全 | 欧美日韩精品电影 | 大荫蒂欧美视频另类xxxx | 欧美精品在线观看一区 | 蜜臀av性久久久久av蜜臀三区 | 亚洲专区欧美专区 | 中文字幕乱码电影 | 在线视频一区二区 | 久久国产乱 | 最新久久久 | 一区在线观看 | 亚洲精品国产免费 | 黄色在线网站噜噜噜 | av在线播放网址 | 狠狠的干 | 久久久久久国产精品999 | 最新av网址大全 | 久久精品久久久精品美女 | 黄色大片免费播放 | 一色屋精品视频在线观看 | 日日爽日日操 | 亚洲国产视频在线 | 高清不卡毛片 | 婷婷中文在线 | av网站地址| 久久九精品 | 亚洲电影黄色 | 国产a国产 | 亚洲精品美女在线 | 婷婷激情欧美 | 99精品在线 | 久久综合婷婷综合 | 亚洲精品视频网站在线观看 | 久久久久久久久免费视频 | 日韩成人精品一区二区三区 | 亚洲精品国产精品国自产 | 天天干天天做天天爱 | 日韩精品久久一区二区 | 在线观看一区视频 | 久久久久在线观看 | 欧美一级日韩免费不卡 | 91精品久久久久久粉嫩 | 色婷婷97| 伊人五月天 | 97国产精品亚洲精品 | 国产精品视频免费观看 | 久久免费高清视频 | 国产精品久久久久久久午夜片 | 久久久久高清毛片一级 | 九九视频在线 | 国产精品久久久久久a | 亚洲一区精品人人爽人人躁 | 日韩欧美久久 | 国产精品资源网 | 深爱激情站 | 中文字幕五区 | 久久视影 | av午夜电影| 日韩免费看视频 | 亚洲日本va午夜在线影院 | 婷婷五月色综合 | 日韩视频中文字幕 | 在线中文字幕播放 | 免费视频在线观看网站 | 国产在线观看地址 | 91色蜜桃 | 91超在线| 久久久精品午夜 | 国产精品毛片久久久久久久 |