UNIX 環(huán)境高級編程|進(jìn)程控制(上)

      網(wǎng)友投稿 838 2022-05-29

      GitHub: https://github.com/storagezhang

      Emai: debugzhang@163.com

      本文為《UNIX 環(huán)境高級編程》第 8 章學(xué)習(xí)筆記

      對在 UNIX 環(huán)境中的高級編程而言,完整地了解 UNIX 的進(jìn)程控制是非常重要的。

      其中必須熟練掌握的只有幾個函數(shù)——fork、exec 系列、_exit、wait 和 waitpid。很多應(yīng)用程序都使用這些簡單的函數(shù)。fork 函數(shù)也給了我們一個了解競爭條件的機(jī)會。

      本章說明了 system 函數(shù)和進(jìn)程會計(jì),這也使我們能進(jìn)一步了解所有這些進(jìn)程控制函數(shù)。

      本章還說明了 exec 函數(shù)的另一種變體:解釋器文件以及它們的工作方式。

      對各種不同的用戶 ID 和組 ID(實(shí)際、有效和保存的)的理解,對編寫安全的設(shè)置用戶 ID 程序是至關(guān)重要的。

      8.2 進(jìn)程標(biāo)識

      每個進(jìn)程都有一個非負(fù)整數(shù)表示的唯一進(jìn)程 ID。

      因?yàn)檫M(jìn)程 ID 標(biāo)識總是唯一的,常將其用作其他標(biāo)識符的一部分以保證其唯一性。

      UNIX 環(huán)境高級編程|進(jìn)程控制(上)

      雖然是唯一的,但是進(jìn)程 ID 是可復(fù)用的。

      當(dāng)一個進(jìn)程終止后,其進(jìn)程 ID 就成為復(fù)用的候選者。

      大多數(shù) UNIX 系統(tǒng)實(shí)現(xiàn)延遲復(fù)用算法,使得賦予新建進(jìn)程的 ID 不同于最近終止進(jìn)程所使用的 ID。

      這防止了將新進(jìn)程誤認(rèn)為是使用同一 ID 的某個已終止的先前進(jìn)程。

      系統(tǒng)中有一些專用進(jìn)程,但具體細(xì)節(jié)隨實(shí)現(xiàn)而不同。

      ID 為 0 的進(jìn)程通常是調(diào)度進(jìn)程,常常被稱為交換進(jìn)程。

      該進(jìn)程是內(nèi)核的一部分,它并不執(zhí)行任何磁盤上的程序,因此也被稱為系統(tǒng)進(jìn)程。

      ID 為 1 的進(jìn)程通常是 init 進(jìn)程,在自舉過程結(jié)束時由內(nèi)核調(diào)用。

      該進(jìn)程的程序文件在 UNIX 早期版本是 /etc/init,在較新的版本中是 /sbin/init。

      該進(jìn)程負(fù)責(zé)在自舉內(nèi)核后啟動一個 UNIX 系統(tǒng)。

      該進(jìn)程通常讀取與系統(tǒng)有關(guān)的初始化文件(/etc/rc* 文件,/etc/inittab 文件以及 /etc/init.d 中的文件),并將系統(tǒng)引導(dǎo)到一個狀態(tài)(如多用戶)。

      該進(jìn)程永遠(yuǎn)不會終止。

      該進(jìn)程是一個普通的用戶進(jìn)程(與交換進(jìn)程不同,它不是內(nèi)核中的系統(tǒng)進(jìn)程),但是它以超級用戶特權(quán)運(yùn)行。

      每個 UNIX 系統(tǒng)實(shí)現(xiàn)都有它自己的一套提供操作系統(tǒng)服務(wù)的內(nèi)核進(jìn)程。

      除了進(jìn)程 ID,每個進(jìn)程還有一些其他標(biāo)識符。下列函數(shù)返回這些標(biāo)識符:

      #include pid_t getpid(void); // 返回值:調(diào)用進(jìn)程的進(jìn)程 ID pid_t getppid(void); // 返回值:調(diào)用進(jìn)程的父進(jìn)程 ID uid_t getuid(void); // 返回值:調(diào)用進(jìn)程的實(shí)際用戶 ID uid_t geteuid(void); // 返回值:調(diào)用進(jìn)程的有效用戶 ID gid_t getgid(void); // 返回值:調(diào)用進(jìn)程的實(shí)際組 ID gid_t getegid(void); // 返回值:調(diào)用進(jìn)程的有效組 ID

      注意:這些函數(shù)都沒有出錯返回。

      8.3 函數(shù) fork

      一個現(xiàn)有的進(jìn)程可以調(diào)用 fork 函數(shù)創(chuàng)建一個新進(jìn)程:

      #include pid_t fork(void); // 返回值:若成功,子進(jìn)程返回 0,父進(jìn)程返回子進(jìn)程 ID;若出錯,返回 -1

      由 fork 創(chuàng)建的新進(jìn)程被稱為子進(jìn)程。

      fork 函數(shù)被調(diào)用一次,但返回兩次。

      將子進(jìn)程 ID 返回給父進(jìn)程的理由是:一個進(jìn)程的子進(jìn)程可以有多個,并且沒有一個函數(shù)使一個進(jìn)程可以獲得其所有子進(jìn)程的進(jìn)程 ID。

      子進(jìn)程繼續(xù)執(zhí)行 fork 調(diào)用之后的指令。

      子進(jìn)程是父進(jìn)程的副本。

      獲得父進(jìn)程數(shù)據(jù)空間、堆和棧的副本。

      父進(jìn)程和子進(jìn)程并不共享這些存儲空間部分。

      父進(jìn)程和子進(jìn)程共享正文段。

      由于在 fork 之后經(jīng)常跟隨著 exec,所以現(xiàn)在的很多實(shí)現(xiàn)并不執(zhí)行一個父進(jìn)程數(shù)據(jù)段、棧和堆的完全副本。

      作為替代,使用了寫時復(fù)制(Copy-On-Write,COW)技術(shù),

      這些區(qū)域由父進(jìn)程和子進(jìn)程共享,而且內(nèi)核將它們的訪問權(quán)限改變?yōu)橹蛔x。

      如果父子進(jìn)程中任一個試圖修改這些區(qū)域,則內(nèi)核只為修改區(qū)域的那塊內(nèi)存制作一個副本,通常是虛擬存儲系統(tǒng)中的一“頁”。

      一般來說,在 fork 之后是父進(jìn)程先執(zhí)行還是子進(jìn)程先執(zhí)行是不確定的,這取決于內(nèi)核所使用的調(diào)度算法。如果要求父進(jìn)程和子進(jìn)程之間相互同步,則要求某種形式的進(jìn)程間通信。

      文件共享

      在重定向父進(jìn)程的標(biāo)準(zhǔn)輸出時,子進(jìn)程的標(biāo)準(zhǔn)輸出也被重定向。

      實(shí)際上,fork 的一個特性是父進(jìn)程的所有打開文件描述符都被復(fù)制到子進(jìn)程中。

      這里的“復(fù)制”,指對每個文件描述符來說,就好像執(zhí)行了 dup 函數(shù)。父進(jìn)程和子進(jìn)程每個相同的打開描述符共享一個文件表項(xiàng)。

      父進(jìn)程和子進(jìn)程共享同一個文件偏移量。

      在 fork 之后處理文件描述符有以下兩種常見的情況:

      父進(jìn)程等待子進(jìn)程完成。

      父進(jìn)程無需對其描述符做任何處理。

      當(dāng)子進(jìn)程終止后,它曾經(jīng)進(jìn)行過讀、寫操作的任一共享描述符的文件偏移量已做了相應(yīng)更新。

      父進(jìn)程和子進(jìn)程各自執(zhí)行不同的程序段。

      父進(jìn)程和子進(jìn)程各自關(guān)閉它們不需要使用的文件描述符,這樣就不會干擾對方使用的文件描述符。這種方法是網(wǎng)絡(luò)服務(wù)進(jìn)程經(jīng)常使用的。

      除了打開文件之外,父進(jìn)程的很多其他屬性也由子進(jìn)程繼承:

      實(shí)際用戶 ID、實(shí)際組 ID、有效用戶 ID、有效組 ID

      附屬組 ID

      進(jìn)程組 ID

      會話 ID

      控制終端

      設(shè)置用戶 ID 標(biāo)志和設(shè)置組 ID 標(biāo)志

      當(dāng)前工作目錄

      根目錄

      文件模式創(chuàng)建屏蔽字

      信號屏蔽和安排

      對任一打開文件描述符的執(zhí)行時關(guān)閉標(biāo)志

      環(huán)境

      連接的共享存儲段

      存儲映像

      資源限制

      父進(jìn)程和子進(jìn)程之間的區(qū)別具體如下:

      fork 的返回值不同

      進(jìn)程 ID 不同

      各自的父進(jìn)程 ID 不同

      子進(jìn)程的 tms_utime,tms_stime,tms_cutime 和 tms_ustime 的值設(shè)置為 0

      子進(jìn)程不繼承父進(jìn)程設(shè)置的文件鎖

      子進(jìn)程的未處理鬧鐘被清除

      子進(jìn)程的未處理信號集設(shè)置為空集

      使 fork 失敗的兩個主要原因是:

      系統(tǒng)中已經(jīng)有了太多的進(jìn)程。

      該實(shí)際用戶 ID 的進(jìn)程總數(shù)超過了系統(tǒng)限制。

      CHILD_MAX 規(guī)定了每個實(shí)際用戶 ID 在任一時刻可擁有的最大進(jìn)程數(shù)。

      fork 有兩種用法:

      一個父進(jìn)程希望復(fù)制自己,使父進(jìn)程和子進(jìn)程同時執(zhí)行不同的代碼段。

      這在網(wǎng)絡(luò)服務(wù)進(jìn)程中是常見的:

      父進(jìn)程等待客戶端的服務(wù)請求。

      當(dāng)這種請求到達(dá)時,父進(jìn)程調(diào)用 fork,使子進(jìn)程處理此請求。

      父進(jìn)程繼續(xù)等待下一個服務(wù)請求。

      一個進(jìn)程要執(zhí)行一個不同的程序。

      這對 shell 是常見的情況:

      子進(jìn)程從 fork 返回后立即調(diào)用 exec。

      8.4 函數(shù) vfork

      vfork 函數(shù)的調(diào)用序列和返回值與 fork 相同,但兩者的語義不同:

      vfork 函數(shù)用于創(chuàng)建一個新進(jìn)程,而該新進(jìn)程的目的是執(zhí)行一個新程序。

      vfork 與 fork 一樣都創(chuàng)建一個子進(jìn)程,但是它并不將父進(jìn)程的地址空間完全復(fù)制到子進(jìn)程中,因?yàn)樽舆M(jìn)程會立即調(diào)用 exec(或 exit),于是也就不會引用該地址空間。

      不過在子進(jìn)程調(diào)用 exec 或 exit 之前,它在父進(jìn)程的空間中運(yùn)行。

      這種優(yōu)化工作方式在某些 UNIX 系統(tǒng)的實(shí)現(xiàn)中提高了效率,但如果子進(jìn)程修改數(shù)據(jù)(除了用于存放 vfork 返回值的變量)、進(jìn)行函數(shù)調(diào)用或者沒有 exec 或 exit 就返回都可能會帶來未知的結(jié)果。

      vfokr 保證子進(jìn)程先運(yùn)行,在它調(diào)用 exec 或 exit 之后父進(jìn)程才可能被調(diào)度運(yùn)行,當(dāng)子進(jìn)程低啊用這兩個函數(shù)中的任意一個時,父進(jìn)程會恢復(fù)運(yùn)行。

      如果在調(diào)用這兩個函數(shù)之前子進(jìn)程依賴于父進(jìn)程的進(jìn)一步動作,則會導(dǎo)致死鎖。

      8.5 函數(shù) exit

      進(jìn)程有 8 種方式使進(jìn)程終止,其中 5 種為正常終止,3 種為異常終止:

      正常終止:

      在 main 函數(shù)內(nèi)執(zhí)行 return 語句。

      這等效于調(diào)用 exit。

      調(diào)用 exit 函數(shù)。

      此函數(shù)由 ISO C 定義,其操作包括調(diào)用個終止處理程序(終止處理程序在調(diào)用 atexit 函數(shù)時登記),然后關(guān)閉所有標(biāo)準(zhǔn) I/O 流等。

      因?yàn)?ISO C 并不處理文件描述符、多進(jìn)程以及作業(yè)控制,所以這一定義對 UNIX 系統(tǒng)而言是不完整的。

      調(diào)用 _exit 或 _Exit 函數(shù)。

      ISO C 定義 _Exit,其目的是為進(jìn)程提供一種無需運(yùn)行終止處理程序或信號處理程序而終止的方法。

      在 UNIX 系統(tǒng)中,_exit 和 _Exit 是同義的,并不沖洗標(biāo)準(zhǔn) I/O 流。

      _exit 是由 POSIX.1 說明的,它由 exit 調(diào)用,處理 UNIX 系統(tǒng)特定的細(xì)節(jié)。

      進(jìn)程的最后一個線程在其啟動例程中執(zhí)行 return 語句。

      該線程的返回值不用作進(jìn)程的返回值。

      當(dāng)最后一個線程從其啟動例程返回時,該進(jìn)程以終止?fàn)顟B(tài) 0 返回。

      進(jìn)程的最后一個線程調(diào)用 pthread_exit 函數(shù)。

      進(jìn)程的終止?fàn)顟B(tài)總是 0,這與傳送給 pthread_exit 的參數(shù)無關(guān)。

      異常終止:

      調(diào)用 abort。

      它產(chǎn)生 SIGABRT 信號,是下一種異常終止的一個特例。

      接到一個信號。

      信號可由進(jìn)程自身(如調(diào)用 abort 函數(shù))、其他進(jìn)程或內(nèi)核產(chǎn)生。

      最后一個線程對“取消”請求作出響應(yīng)。

      默認(rèn)情況下,“取消”以延遲的方式發(fā)生:一個線程要求取消另一個線程,若干時間之后,目標(biāo)線程終止。

      不管進(jìn)程如何終止,最后都會執(zhí)行內(nèi)核中的同一段代碼。這段代碼為相應(yīng)進(jìn)程關(guān)閉所有打開描述符,釋放它對所使用的存儲器等。

      對上述任意一種終止情形,我們都希望終止進(jìn)程能夠通知其父進(jìn)程它是如何終止的。

      對于 3 個終止函數(shù),實(shí)現(xiàn)這一點(diǎn)的方法是,將其退出狀態(tài)作為參數(shù)傳遞給函數(shù)。

      在異常終止情況下,該終止進(jìn)程的父進(jìn)程都能用 wait 或 waitpid 函數(shù)取得其終止?fàn)顟B(tài)。

      注意,退出狀態(tài)是傳遞給 3 個終止函數(shù)的參數(shù),或 main 的返回值,在最后調(diào)用 _exit 時,內(nèi)核將退出狀態(tài)轉(zhuǎn)換成終止?fàn)顟B(tài)。

      如果子進(jìn)程先終止:

      子進(jìn)程將其終止?fàn)顟B(tài)返回給父進(jìn)程。

      如果父進(jìn)程先終止:

      對于父進(jìn)程已經(jīng)終止的所有進(jìn)程,它們的父進(jìn)程都改為 init 進(jìn)程。

      我們稱這些進(jìn)程由 init 進(jìn)程收養(yǎng),其操作過程大致是:

      在一個進(jìn)程終止時,內(nèi)核逐個檢查所有活動進(jìn)程,以判斷它是否是正要終止進(jìn)程的子進(jìn)程,如果是,則該進(jìn)程的父進(jìn)程 ID 就更改為 1。

      這種處理方法保證了每個進(jìn)程有一個父進(jìn)程。

      內(nèi)核為每個終止子進(jìn)程保存了一定量的信息,所以當(dāng)終止進(jìn)程的父進(jìn)程調(diào)用 wait 函數(shù)或者 waitpid 函數(shù)時,可以得到這些信息。

      這些信息至少包括:終止進(jìn)程的進(jìn)程 ID、該進(jìn)程的終止?fàn)顟B(tài)、該進(jìn)程使用的 CPU 時間總量。

      一個已經(jīng)終止、但是等待父進(jìn)程對它進(jìn)行善后處理的進(jìn)程稱作僵死進(jìn)程,在 ps 命令中顯示為 Z。

      所謂善后處理,就是父進(jìn)程調(diào)用 wait 函數(shù)或者 waitpid 函數(shù)讀取終止進(jìn)程的殘留信息

      一旦父進(jìn)程進(jìn)行了善后處理,則終止進(jìn)程的所有占用資源(包括殘留信息)都得到釋放,該進(jìn)程被徹底銷毀

      對于 init 進(jìn)程:

      任何時候只要有一個子進(jìn)程終止,就立即調(diào)用 wait 函數(shù)取得其終止?fàn)顟B(tài)。

      這種做法防止系統(tǒng)中塞滿了僵死進(jìn)程。

      8.6 函數(shù) wait 和 waitpid

      當(dāng)一個進(jìn)程正?;虍惓=K止時,內(nèi)核就向其父進(jìn)程發(fā)送 SIGCHLD 信號。

      因?yàn)樽舆M(jìn)程終止是一個異步事件,所以這種信號是內(nèi)核向父進(jìn)程發(fā)送的異步進(jìn)程。

      父進(jìn)程可以選擇忽略該信號。這是系統(tǒng)的默認(rèn)動作。

      父進(jìn)程也可以提供一個該信號發(fā)生時即被調(diào)用執(zhí)行的函數(shù)(信號處理程序)。

      如果進(jìn)程由于接收到 SIGCHLD 信號而調(diào)用 wait,我們期望 wait 會立即返回。

      但是如果在隨機(jī)時間點(diǎn)調(diào)用 wait,則進(jìn)程可能會阻塞。

      #include pid_t wait(int *statloc); pid_t waitpid(pid_t pid, int *statloc, int options); // 返回值:若成功,返回進(jìn)程 ID;若出錯,返回 0 或 -1

      區(qū)別:

      在一個子進(jìn)程終止前,wait 使其調(diào)用者阻塞,而 waitpid 有一選項(xiàng),可使調(diào)用者不阻塞。

      waitpid 并不等待在其調(diào)用之后的第一個終止子進(jìn)程,它有若干個選項(xiàng),可以控制它所等待的進(jìn)程。

      如果子進(jìn)程已經(jīng)終止,并且是一個僵死進(jìn)程,則 wait 立即返回并取得該子進(jìn)程的狀態(tài);否則 wait 使其調(diào)用者阻塞,直到一個子進(jìn)程終止。

      如果調(diào)用者阻塞而且它有多個子進(jìn)程,則在其某一子進(jìn)程終止時,wait 就立即返回。

      因?yàn)?wait 返回終止子進(jìn)程的進(jìn)程 ID,所以它總能了解是哪一個子進(jìn)程終止了。

      waitpid 可等待一個特定進(jìn)程,而 wait 則返回任一終止子進(jìn)程的狀態(tài)。

      waitpid 提供了一個 wait 的非阻塞版本。有時希望獲取一個子進(jìn)程的狀態(tài),但不想阻塞。

      參數(shù):

      staloc:存放子進(jìn)程終止?fàn)顟B(tài)的地址。

      如果不關(guān)心子進(jìn)程的終止?fàn)顟B(tài),可以將該參數(shù)設(shè)為空指針。

      pid:

      如果 pid==-1:則等待任一子進(jìn)程終止。

      如果 pid>0:則等待進(jìn)程 ID 等于 pid 的那個子進(jìn)程終止。

      如果 pid==0:則等待組 ID 等于調(diào)用進(jìn)程組 ID 的任一子進(jìn)程終止。

      如果 pid<0:等待組 ID 等于 pid 絕對值的任一子進(jìn)程終止。

      options:使我們進(jìn)一步控制 waitpid 的操作。

      或者是0,或者是下列常量按位或的結(jié)果:

      有 4 個互斥的宏可用來取得進(jìn)程終止的原因,它們的名字都以 WIF 開始?;谶@ 4 個宏中哪一個值為真,就可選用其他宏來取得退出狀態(tài)、信號編號等。

      8.7 函數(shù) waitid

      Single UNIX Specification 包括了另一個取得進(jìn)程終止?fàn)顟B(tài)的函數(shù)——waitid,此函數(shù)類似于 waitpid,但提供了更多的靈活性。

      #include int waitid(id_type_t idtype, id_t id, siginfo_t *infop, int options); // 返回值:若成功,返回 0;若出錯,返回 -1

      參數(shù):

      idtype:可以為下列常量:

      id:指定要等待的子進(jìn)程 ID,其作用與 idtype 的值相關(guān)。

      infop:一個緩沖區(qū)的地址。

      該緩沖區(qū)由 waitid 填寫,包含了造成子進(jìn)程狀態(tài)改變的有關(guān)信號的詳細(xì)信息。

      options:指示調(diào)用者關(guān)注哪些狀態(tài)變化??梢允窍铝谐A康陌次换颍?/p>

      WCONTINUED、WEXITED 或 WSTOPPED 這 3 個常量之一必須在 options 參數(shù)中指定。

      8.8 函數(shù) wait3 和 wait4

      函數(shù) wait3 和 wait4 提供的功能比 wait、waitpid 和 waitid 所提供的功能要多一個,這與附加參數(shù)有關(guān)。該參數(shù)允許內(nèi)核返回由終止進(jìn)程及其所有子進(jìn)程使用的資源概況。

      #include #include #include #include pid_t wait3(int *statloc, int options, struct rusage *rusage); pid_t wait4(pid_t pid, int *statloc, int options, struct rusage *rusage); // 返回值:若成功,返回進(jìn)程 ID;若出錯,返回 -1

      參數(shù):

      statloc:存放子進(jìn)程終止?fàn)顟B(tài)的緩沖區(qū)的地址。

      如果不關(guān)心子進(jìn)程的終止?fàn)顟B(tài),可以將它設(shè)為空指針。

      rusage:存放由 wait3 和 wait4 返回的終止子進(jìn)程的資源統(tǒng)計(jì)信息的緩沖區(qū)地址。

      資源統(tǒng)計(jì)信息包括用戶 CPU 時間總量、系統(tǒng) CPU 時間總量、缺頁次數(shù)、接收到信號的次數(shù)等。

      pid 和 options 參數(shù)的意義與 waitpid 相同。

      8.9 競爭條件

      當(dāng)多個進(jìn)程都企圖對共享數(shù)據(jù)進(jìn)行某種處理,而最后的結(jié)果又取決于進(jìn)程運(yùn)行的順序時,我們認(rèn)為發(fā)生了競爭條件。

      如果在 fork 之后的某種邏輯顯式或隱式地依賴于在 fork 之后是父進(jìn)程先運(yùn)行還是子進(jìn)程先運(yùn)行,那么 fork 函數(shù)就會是競爭條件活躍的滋生地。

      如果一個進(jìn)程希望等待一個子進(jìn)程終止,則它必須調(diào)用 wait 函數(shù)中的一個。如果一個進(jìn)程要等待其父進(jìn)程終止,則可使用下列形式的循環(huán):

      while (getppid() != 1) { sleep(1); }

      這種形式的循環(huán)稱為輪詢,它的問題是浪費(fèi)了 CPU 時間,因?yàn)檎{(diào)用者每隔 1s 都被喚醒,然后進(jìn)行條件測試。

      為了避免競爭條件和輪詢,在多個進(jìn)程之間需要有某種形式的信號發(fā)送和接收的方法。在 UNIX 中可以使用信號機(jī)制,各種形式的進(jìn)程間通信(IPC)也可以使用。

      Linux Unix

      版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實(shí)的內(nèi)容,請聯(lián)系我們jiasou666@gmail.com 處理,核實(shí)后本網(wǎng)站將在24小時內(nèi)刪除侵權(quán)內(nèi)容。

      上一篇:Unix基礎(chǔ)之環(huán)境變量
      下一篇:Imagemagick常用指令
      相關(guān)文章
      亚洲AV日韩综合一区尤物| 亚洲an天堂an在线观看| 亚洲综合色视频在线观看| 亚洲一区免费在线观看| 日韩精品亚洲人成在线观看 | 亚洲午夜在线一区| 中文字幕亚洲第一在线| 亚洲无删减国产精品一区| 久久精品国产亚洲AV麻豆不卡| 亚洲自偷自偷偷色无码中文| 亚洲综合伊人久久大杳蕉| 91麻豆精品国产自产在线观看亚洲 | 国产成人精品日本亚洲| 亚洲精品卡2卡3卡4卡5卡区| 亚洲精品无码不卡在线播放HE | 久久精品国产亚洲麻豆| 久久亚洲国产中v天仙www| 亚洲Av无码专区国产乱码DVD | 亚洲aⅴ无码专区在线观看| 亚洲aⅴ无码专区在线观看| 亚洲成人一区二区| 亚洲国产一成久久精品国产成人综合| 日韩精品电影一区亚洲| 亚洲人成网站色在线入口| 在线观看亚洲精品福利片| 国产精品国产亚洲精品看不卡| 亚洲第一视频网站| 久久精品国产亚洲av影院| 亚洲激情黄色小说| 亚洲国产日韩综合久久精品| 亚洲国产精品自在自线观看| 人人狠狠综合久久亚洲高清| 美腿丝袜亚洲综合| 亚洲AV无码国产精品麻豆天美 | 亚洲精品国精品久久99热 | 亚洲色成人网站WWW永久四虎 | 国产亚洲高清在线精品不卡| 国产亚洲成人久久| 久久久久亚洲精品影视| 亚洲最大在线视频| 亚洲天然素人无码专区|