• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            posts - 200, comments - 8, trackbacks - 0, articles - 0

            當(dāng) Linux 最初開發(fā)時(shí),在內(nèi)核中并不能真正支持線程。但是它的確可以通過 clone() 系統(tǒng)調(diào)用將進(jìn)程作為可調(diào)度的實(shí)體。這個(gè)調(diào)用創(chuàng)建了調(diào)用進(jìn)程(calling process)的一個(gè)拷貝,這個(gè)拷貝與調(diào)用進(jìn)程共享相同的地址空間。LinuxThreads 項(xiàng)目使用這個(gè)調(diào)用來完全在用戶空間模擬對(duì)線程的支持。不幸的是,這種方法有一些缺點(diǎn),尤其是在信號(hào)處理、調(diào)度和進(jìn)程間同步原語方面都存在問題。另外,這個(gè) 線程模型也不符合 POSIX 的要求。

            要改進(jìn) LinuxThreads,非常明顯我們需要內(nèi)核的支持,并且需要重寫線程庫。有兩個(gè)相互競爭的項(xiàng)目開始來滿足這些要求。一個(gè)包括 IBM 的開發(fā)人員的團(tuán)隊(duì)開展了 NGPT(Next-Generation POSIX Threads)項(xiàng)目。同時(shí),Red Hat 的一些開發(fā)人員開展了 NPTL 項(xiàng)目。NGPT 在 2003 年中期被放棄了,把這個(gè)領(lǐng)域完全留給了 NPTL。

            盡管從 LinuxThreads 到 NPTL 看起來似乎是一個(gè)必然的過程,但是如果您正在為一個(gè)歷史悠久的 Linux 發(fā)行版維護(hù)一些應(yīng)用程序,并且計(jì)劃很快就要進(jìn)行升級(jí),那么如何遷移到 NPTL 上就會(huì)變成整個(gè)移植過程中重要的一個(gè)部分。另外,我們可能會(huì)希望了解二者之間的區(qū)別,這樣就可以對(duì)自己的應(yīng)用程序進(jìn)行設(shè)計(jì),使其能夠更好地利用這兩種技 術(shù)。

            本文詳細(xì)介紹了這些線程模型分別是在哪些發(fā)行版上實(shí)現(xiàn)的。

            LinuxThreads 設(shè)計(jì)細(xì)節(jié)

            線程 將應(yīng)用程序劃分成一個(gè)或多個(gè)同時(shí)運(yùn)行的任務(wù)。線程與傳統(tǒng)的多任務(wù)進(jìn)程 之間的區(qū)別在于:線程共享的是單個(gè)進(jìn)程的狀態(tài)信息,并會(huì)直接共享內(nèi)存和其他資源。同一個(gè)進(jìn)程中線程之間的上下文切換通常要比進(jìn)程之間的上下文切換速度更 快。因此,多線程程序的優(yōu)點(diǎn)就是它可以比多進(jìn)程應(yīng)用程序的執(zhí)行速度更快。另外,使用線程我們可以實(shí)現(xiàn)并行處理。這些相對(duì)于基于進(jìn)程的方法所具有的優(yōu)點(diǎn)推動(dòng) 了 LinuxThreads 的實(shí)現(xiàn)。

            LinuxThreads 最初的設(shè)計(jì)相信相關(guān)進(jìn)程之間的上下文切換速度很快,因此每個(gè)內(nèi)核線程足以處理很多相關(guān)的用戶級(jí)線程。這就導(dǎo)致了一對(duì)一 線程模型的革命。

            讓我們來回顧一下 LinuxThreads 設(shè)計(jì)細(xì)節(jié)的一些基本理念:

            • LinuxThreads 非常出名的一個(gè)特性就是管理線程(manager thread)。管理線程可以滿足以下要求:

              • 系統(tǒng)必須能夠響應(yīng)終止信號(hào)并殺死整個(gè)進(jìn)程。
              • 以堆棧形式使用的內(nèi)存回收必須在線程完成之后進(jìn)行。因此,線程無法自行完成這個(gè)過程。
              • 終止線程必須進(jìn)行等待,這樣它們才不會(huì)進(jìn)入僵尸狀態(tài)。
              • 線程本地?cái)?shù)據(jù)的回收需要對(duì)所有線程進(jìn)行遍歷;這必須由管理線程來進(jìn)行。
              • 如果主線程需要調(diào)用 pthread_exit(),那么這個(gè)線程就無法結(jié)束。主線程要進(jìn)入睡眠狀態(tài),而管理線程的工作就是在所有線程都被殺死之后來喚醒這個(gè)主線程。

            • 為了維護(hù)線程本地?cái)?shù)據(jù)和內(nèi)存,LinuxThreads 使用了進(jìn)程地址空間的高位內(nèi)存(就在堆棧地址之下)。

            • 原語的同步是使用信號(hào) 來實(shí)現(xiàn)的。例如,線程會(huì)一直阻塞,直到被信號(hào)喚醒為止。

            • 在克隆系統(tǒng)的最初設(shè)計(jì)之下,LinuxThreads 將每個(gè)線程都是作為一個(gè)具有惟一進(jìn)程 ID 的進(jìn)程實(shí)現(xiàn)的。

            • 終止信號(hào)可以殺死所有的線程。LinuxThreads 接收到終止信號(hào)之后,管理線程就會(huì)使用相同的信號(hào)殺死所有其他線程(進(jìn)程)。

            • 根據(jù) LinuxThreads 的設(shè)計(jì),如果一個(gè)異步信號(hào)被發(fā)送了,那么管理線程就會(huì)將這個(gè)信號(hào)發(fā)送給一個(gè)線程。如果這個(gè)線程現(xiàn)在阻塞了這個(gè)信號(hào),那么這個(gè)信號(hào)也就會(huì)被掛起。這是因?yàn)楣芾砭€程無法將這個(gè)信號(hào)發(fā)送給進(jìn)程;相反,每個(gè)線程都是作為一個(gè)進(jìn)程在執(zhí)行。

            • 線程之間的調(diào)度是由內(nèi)核調(diào)度器來處理的。

            LinuxThreads 及其局限性

            LinuxThreads 的設(shè)計(jì)通常都可以很好地工作;但是在壓力很大的應(yīng)用程序中,它的性能、可伸縮性和可用性都會(huì)存在問題。下面讓我們來看一下 LinuxThreads 設(shè)計(jì)的一些局限性:

            • 它使用管理線程來創(chuàng)建線程,并對(duì)每個(gè)進(jìn)程所擁有的所有線程進(jìn)行協(xié)調(diào)。這增加了創(chuàng)建和銷毀線程所需要的開銷。

            • 由于它是圍繞一個(gè)管理線程來設(shè)計(jì)的,因此會(huì)導(dǎo)致很多的上下文切換的開銷,這可能會(huì)妨礙系統(tǒng)的可伸縮性和性能。

            • 由于管理線程只能在一個(gè) CPU 上運(yùn)行,因此所執(zhí)行的同步操作在 SMP 或 NUMA 系統(tǒng)上可能會(huì)產(chǎn)生可伸縮性的問題。

            • 由于線程的管理方式,以及每個(gè)線程都使用了一個(gè)不同的進(jìn)程 ID,因此 LinuxThreads 與其他與 POSIX 相關(guān)的線程庫并不兼容。

            • 信號(hào)用來實(shí)現(xiàn)同步原語,這會(huì)影響操作的響應(yīng)時(shí)間。另外,將信號(hào)發(fā)送到主進(jìn)程的概念也并不存在。因此,這并不遵守 POSIX 中處理信號(hào)的方法。

            • LinuxThreads 中對(duì)信號(hào)的處理是按照每線程的原則建立的,而不是按照每進(jìn)程的原則建立的,這是因?yàn)槊總€(gè)線程都有一個(gè)獨(dú)立的進(jìn)程 ID。由于信號(hào)被發(fā)送給了一個(gè)專用的線程,因此信號(hào)是串行化的 —— 也就是說,信號(hào)是透過這個(gè)線程再傳遞給其他線程的。這與 POSIX 標(biāo)準(zhǔn)對(duì)線程進(jìn)行并行處理的要求形成了鮮明的對(duì)比。例如,在 LinuxThreads 中,通過 kill() 所發(fā)送的信號(hào)被傳遞到一些單獨(dú)的線程,而不是集中整體進(jìn)行處理。這意味著如果有線程阻塞了這個(gè)信號(hào),那么 LinuxThreads 就只能對(duì)這個(gè)線程進(jìn)行排隊(duì),并在線程開放這個(gè)信號(hào)時(shí)在執(zhí)行處理,而不是像其他沒有阻塞信號(hào)的線程中一樣立即處理這個(gè)信號(hào)。

            • 由于 LinuxThreads 中的每個(gè)線程都是一個(gè)進(jìn)程,因此用戶和組 ID 的信息可能對(duì)單個(gè)進(jìn)程中的所有線程來說都不是通用的。例如,一個(gè)多線程的 setuid()/setgid() 進(jìn)程對(duì)于不同的線程來說可能都是不同的。

            • 有一些情況下,所創(chuàng)建的多線程核心轉(zhuǎn)儲(chǔ)中并沒有包含所有的線程信息。同樣,這種行為也是每個(gè)線程都是一個(gè)進(jìn)程這個(gè)事實(shí)所導(dǎo)致的結(jié)果。如果任何線程 發(fā)生了問題,我們?cè)谙到y(tǒng)的核心文件中只能看到這個(gè)線程的信息。不過,這種行為主要適用于早期版本的 LinuxThreads 實(shí)現(xiàn)。

            • 由于每個(gè)線程都是一個(gè)單獨(dú)的進(jìn)程,因此 /proc 目錄中會(huì)充滿眾多的進(jìn)程項(xiàng),而這實(shí)際上應(yīng)該是線程。

            • 由于每個(gè)線程都是一個(gè)進(jìn)程,因此對(duì)每個(gè)應(yīng)用程序只能創(chuàng)建有限數(shù)目的線程。例如,在 IA32 系統(tǒng)上,可用進(jìn)程總數(shù) —— 也就是可以創(chuàng)建的線程總數(shù) —— 是 4,090。

            • 由于計(jì)算線程本地?cái)?shù)據(jù)的方法是基于堆棧地址的位置的,因此對(duì)于這些數(shù)據(jù)的訪問速度都很慢。另外一個(gè)缺點(diǎn)是用戶無法可信地指定堆棧的大小,因?yàn)橛脩艨赡軙?huì)意外地將堆棧地址映射到本來要為其他目的所使用的區(qū)域上了。按需增長(grow on demand) 的概念(也稱為浮動(dòng)堆棧 的概念)是在 2.4.10 版本的 Linux 內(nèi)核中實(shí)現(xiàn)的。在此之前,LinuxThreads 使用的是固定堆棧。

            關(guān)于 NPTL

            NPTL,或稱為 Native POSIX Thread Library,是 Linux 線程的一個(gè)新實(shí)現(xiàn),它克服了 LinuxThreads 的缺點(diǎn),同時(shí)也符合 POSIX 的需求。與 LinuxThreads 相比,它在性能和穩(wěn)定性方面都提供了重大的改進(jìn)。與 LinuxThreads 一樣,NPTL 也實(shí)現(xiàn)了一對(duì)一的模型。

            Ulrich Drepper 和 Ingo Molnar 是 Red Hat 參與 NPTL 設(shè)計(jì)的兩名員工。他們的總體設(shè)計(jì)目標(biāo)如下:

            • 這個(gè)新線程庫應(yīng)該兼容 POSIX 標(biāo)準(zhǔn)。

            • 這個(gè)線程實(shí)現(xiàn)應(yīng)該在具有很多處理器的系統(tǒng)上也能很好地工作。

            • 為一小段任務(wù)創(chuàng)建新線程應(yīng)該具有很低的啟動(dòng)成本。

            • NPTL 線程庫應(yīng)該與 LinuxThreads 是二進(jìn)制兼容的。注意,為此我們可以使用 LD_ASSUME_KERNEL,這會(huì)在本文稍后進(jìn)行討論。

            • 這個(gè)新線程庫應(yīng)該可以利用 NUMA 支持的優(yōu)點(diǎn)。

            NPTL 的優(yōu)點(diǎn)

            與 LinuxThreads 相比,NPTL 具有很多優(yōu)點(diǎn):

            • NPTL 沒有使用管理線程。管理線程的一些需求,例如向作為進(jìn)程一部分的所有線程發(fā)送終止信號(hào),是并不需要的;因?yàn)閮?nèi)核本身就可以實(shí)現(xiàn)這些功能。內(nèi)核還會(huì)處理每個(gè) 線程堆棧所使用的內(nèi)存的回收工作。它甚至還通過在清除父線程之前進(jìn)行等待,從而實(shí)現(xiàn)對(duì)所有線程結(jié)束的管理,這樣可以避免僵尸進(jìn)程的問題。

            • 由于 NPTL 沒有使用管理線程,因此其線程模型在 NUMA 和 SMP 系統(tǒng)上具有更好的可伸縮性和同步機(jī)制。

            • 使用 NPTL 線程庫與新內(nèi)核實(shí)現(xiàn),就可以避免使用信號(hào)來對(duì)線程進(jìn)行同步了。為了這個(gè)目的,NPTL 引入了一種名為futex 的新機(jī)制。futex 在共享內(nèi)存區(qū)域上進(jìn)行工作,因此可以在進(jìn)程之間進(jìn)行共享,這樣就可以提供進(jìn)程間 POSIX 同步機(jī)制。我們也可以在進(jìn)程之間共享一個(gè) futex。這種行為使得進(jìn)程間同步成為可能。實(shí)際上,NPTL 包含了一個(gè) PTHREAD_PROCESS_SHARED 宏,使得開發(fā)人員可以讓用戶級(jí)進(jìn)程在不同進(jìn)程的線程之間共享互斥鎖。

            • 由于 NPTL 是 POSIX 兼容的,因此它對(duì)信號(hào)的處理是按照每進(jìn)程的原則進(jìn)行的;getpid() 會(huì)為所有的線程返回相同的進(jìn)程 ID。例如,如果發(fā)送了 SIGSTOP 信號(hào),那么整個(gè)進(jìn)程都會(huì)停止;使用 LinuxThreads,只有接收到這個(gè)信號(hào)的線程才會(huì)停止。這樣可以在基于 NPTL 的應(yīng)用程序上更好地利用調(diào)試器,例如 GDB。

            • 由于在 NPTL 中所有線程都具有一個(gè)父進(jìn)程,因此對(duì)父進(jìn)程匯報(bào)的資源使用情況(例如 CPU 和內(nèi)存百分比)都是對(duì)整個(gè)進(jìn)程進(jìn)行統(tǒng)計(jì)的,而不是對(duì)一個(gè)線程進(jìn)行統(tǒng)計(jì)的。

            • NPTL 線程庫所引入的一個(gè)實(shí)現(xiàn)特性是對(duì) ABI(應(yīng)用程序二進(jìn)制接口)的支持。這幫助實(shí)現(xiàn)了與 LinuxThreads 的向后兼容性。這個(gè)特性是通過使用 LD_ASSUME_KERNEL 實(shí)現(xiàn)的,下面就來介紹這個(gè)特性。

            LD_ASSUME_KERNEL 環(huán)境變量

            正如上面介紹的一樣,ABI 的引入使得可以同時(shí)支持 NPTL 和 LinuxThreads 模型。基本上來說,這是通過 ld (一個(gè)動(dòng)態(tài)鏈接器/加載器)來進(jìn)行處理的,它會(huì)決定動(dòng)態(tài)鏈接到哪個(gè)運(yùn)行時(shí)線程庫上。

            舉例來說,下面是 WebSphere® Application Server 對(duì)這個(gè)變量所使用的一些通用設(shè)置;您可以根據(jù)自己的需要進(jìn)行適當(dāng)?shù)脑O(shè)置:

            • LD_ASSUME_KERNEL=2.4.19:這會(huì)覆蓋 NPTL 的實(shí)現(xiàn)。這種實(shí)現(xiàn)通常都表示使用標(biāo)準(zhǔn)的 LinuxThreads 模型,并啟用浮動(dòng)堆棧的特性。
            • LD_ASSUME_KERNEL=2.2.5:這會(huì)覆蓋 NPTL 的實(shí)現(xiàn)。這種實(shí)現(xiàn)通常都表示使用 LinuxThreads 模型,同時(shí)使用固定堆棧大小。

            我們可以使用下面的命令來設(shè)置這個(gè)變量:

            export LD_ASSUME_KERNEL=2.4.19

            注意,對(duì)于任何 LD_ASSUME_KERNEL 設(shè)置的支持都取決于目前所支持的線程庫的 ABI 版本。例如,如果線程庫并不支持 2.2.5 版本的 ABI,那么用戶就不能將 LD_ASSUME_KERNEL 設(shè)置為 2.2.5。通常,NPTL 需要 2.4.20,而 LinuxThreads 則需要 2.4.1。

            如果您正運(yùn)行的是一個(gè)啟用了 NPTL 的 Linux 發(fā)行版,但是應(yīng)用程序卻是基于 LinuxThreads 模型來設(shè)計(jì)的,那么所有這些設(shè)置通常都可以使用。

            GNU_LIBPTHREAD_VERSION 宏

            大部分現(xiàn)代 Linux 發(fā)行版都預(yù)裝了 LinuxThreads 和 NPTL,因此它們提供了一種機(jī)制來在二者之間進(jìn)行切換。要查看您的系統(tǒng)上正在使用的是哪個(gè)線程庫,請(qǐng)運(yùn)行下面的命令:

            $ getconf GNU_LIBPTHREAD_VERSION

            這會(huì)產(chǎn)生類似于下面的輸出結(jié)果:

            NPTL 0.34

            或者:

            linuxthreads-0.10

            Linux 發(fā)行版所使用的線程模型、glibc 版本和內(nèi)核版本

            表 1 列出了一些流行的 Linux 發(fā)行版,以及它們所采用的線程實(shí)現(xiàn)的類型、glibc 庫和內(nèi)核版本。

            表 1. Linux 發(fā)行版及其線程實(shí)現(xiàn)
            線程實(shí)現(xiàn)C 庫發(fā)行版內(nèi)核
            LinuxThreads 0.7, 0.71 (for libc5)libc 5.xRed Hat 4.2
            LinuxThreads 0.7, 0.71 (for glibc 2)glibc 2.0.xRed Hat 5.x
            LinuxThreads 0.8glibc 2.1.1Red Hat 6.0
            LinuxThreads 0.8glibc 2.1.2Red Hat 6.1 and 6.2
            LinuxThreads 0.9
            Red Hat 7.22.4.7
            LinuxThreads 0.9glibc 2.2.4Red Hat 2.1 AS2.4.9
            LinuxThreads 0.10glibc 2.2.93Red Hat 8.02.4.18
            NPTL 0.6glibc 2.3Red Hat 9.02.4.20
            NPTL 0.61glibc 2.3.2Red Hat 3.0 EL2.4.21
            NPTL 2.3.4glibc 2.3.4Red Hat 4.02.6.9
            LinuxThreads 0.9glibc 2.2SUSE Linux Enterprise Server 7.12.4.18
            LinuxThreads 0.9glibc 2.2.5SUSE Linux Enterprise Server 82.4.21
            LinuxThreads 0.9glibc 2.2.5United Linux2.4.21
            NPTL 2.3.5glibc 2.3.3SUSE Linux Enterprise Server 92.6.5

            注意,從 2.6.x 版本的內(nèi)核和 glibc 2.3.3 開始,NPTL 所采用的版本號(hào)命名約定發(fā)生了變化:這個(gè)庫現(xiàn)在是根據(jù)所使用的 glibc 的版本進(jìn)行編號(hào)的。

            Java™ 虛擬機(jī)(JVM)的支持可能會(huì)稍有不同。IBM 的 JVM 可以支持表 1 中 glibc 版本高于 2.1 的大部分發(fā)行版。

            結(jié)束語

            LinuxThreads 的限制已經(jīng)在 NPTL 以及 LinuxThreads 后期的一些版本中得到了克服。例如,最新的 LinuxThreads 實(shí)現(xiàn)使用了線程注冊(cè)來定位線程本地?cái)?shù)據(jù);例如在 Intel® 處理器上,它就使用了 %fs 和 %gs 段寄存器來定位訪問線程本地?cái)?shù)據(jù)所使用的虛擬地址。盡管這個(gè)結(jié)果展示了 LinuxThreads 所采納的一些修改的改進(jìn)結(jié)果,但是它在更高負(fù)載和壓力測(cè)試中,依然存在很多問題,因?yàn)樗^分地依賴于一個(gè)管理線程,使用它來進(jìn)行信號(hào)處理等操作。

            您應(yīng)該記住,在使用 LinuxThreads 構(gòu)建庫時(shí),需要使用 -D_REENTRANT 編譯時(shí)標(biāo)志。這使得庫線程是安全的。

            最后,也許是最重要的事情,請(qǐng)記住 LinuxThreads 項(xiàng)目的創(chuàng)建者已經(jīng)不再積極更新它了,他們認(rèn)為 NPTL 會(huì)取代 LinuxThreads。

            LinuxThreads 的缺點(diǎn)并不意味著 NPTL 就沒有錯(cuò)誤。作為一個(gè)面向 SMP 的設(shè)計(jì),NPTL 也有一些缺點(diǎn)。我曾經(jīng)看到過在最近的 Red Hat 內(nèi)核上出現(xiàn)過這樣的問題:一個(gè)簡單線程在單處理器的機(jī)器上運(yùn)行良好,但在 SMP 機(jī)器上卻掛起了。我相信在 Linux 上還有更多工作要做才能使它具有更好的可伸縮性,從而滿足高端應(yīng)用程序的需求。


            參考資料

            學(xué)習(xí)

            • 您可以參閱本文在 developerWorks 全球站點(diǎn)上的 英文原文 。

            • Ulrich Drepper 和 Ingo Molnar 編寫的 “The Native POSIX Thread Library for Linux”(PDF)介紹了設(shè)計(jì) NPTL 的原因和目標(biāo),其中包括了 LinuxThreads 的缺點(diǎn)和 NPTL 的優(yōu)點(diǎn)。 

            • LinuxThreads FAQ 包含了有關(guān) LinuxThreads 和 NPTL 的常見問題。這對(duì)于了解早期的 LinuxThreads 實(shí)現(xiàn)的缺點(diǎn)來說是一個(gè)很好的資源。 

            • Ulrich Drepper 撰寫的 “Explaining LD_ASSUME_KERNEL” 提供了有關(guān)這個(gè)環(huán)境變量的詳細(xì)介紹。 

            • “Native POSIX Threading Library (NPTL) support” 從 WebSphere 的視角介紹了 LinuxThreads 和 NPTL 之間的區(qū)別,并解釋了 WebSphere Application Server 如何支持這兩種不同的線程模型。 

            • Diagnosis documentation for IBM ports of the JVM 定義了 Java 應(yīng)用程序在 Linux 上運(yùn)行時(shí)面臨問題時(shí)所要搜集的診斷信息。 

            • 在 developerWorks Linux 專區(qū) 中可以找到為 Linux 開發(fā)人員準(zhǔn)備的更多資源。 

            • 隨時(shí)關(guān)注 developerWorks 技術(shù)事件和網(wǎng)絡(luò)廣播。 

            獲得產(chǎn)品和技術(shù)

            • LinuxThreads README 對(duì) LinuxThreads 概要進(jìn)行了介紹。 

            • 在您的下一個(gè)開發(fā)項(xiàng)目中采用 IBM 試用軟件,這可以從 developerWorks 上直接下載。 

            討論

            • 通過參與 developerWorks blogs 加入 developerWorks 社區(qū)。 

            關(guān)于作者

            Vikram Shukla 具有 6 年使用面向?qū)ο笳Z言進(jìn)行開發(fā)和設(shè)計(jì)的經(jīng)驗(yàn),目前是位于印度 Banglore 的 IBM Java Technology Center 的一名資深軟件工程師,負(fù)責(zé)對(duì) IBM JVM on Linux 進(jìn)行支持。

            轉(zhuǎn)自:http://blog.chinaunix.net/uid-20556054-id-3068081.html

            久久夜色精品国产欧美乱| 久久精品九九亚洲精品| 99久久99这里只有免费的精品| 无码8090精品久久一区| 欧美一区二区精品久久| 97精品伊人久久大香线蕉app| 蜜臀av性久久久久蜜臀aⅴ麻豆| 奇米影视7777久久精品人人爽| 久久精品国产亚洲AV不卡| 国产成人精品久久综合| 国内精品久久久久久久97牛牛| 亚洲AV日韩AV天堂久久| 亚洲精品乱码久久久久久| 99蜜桃臀久久久欧美精品网站 | 日本精品久久久久中文字幕| 欧洲精品久久久av无码电影| 男女久久久国产一区二区三区| 无码日韩人妻精品久久蜜桃 | 成人国内精品久久久久影院| 精品久久久久久无码中文字幕一区| 久久久精品国产免大香伊| 国内精品综合久久久40p| 亚洲精品无码专区久久久| 精品久久久久久国产潘金莲| A级毛片无码久久精品免费| 久久精品国产亚洲av麻豆小说| 国内精品久久久久伊人av| 国产99久久久国产精品~~牛| 久久久久久国产精品免费免费 | 久久人人爽人人爽人人片AV高清| 久久午夜夜伦鲁鲁片免费无码影视| 国产美女亚洲精品久久久综合| 久久精品国产亚洲AV无码娇色| 伊人色综合久久天天| 久久中文字幕视频、最近更新| 久久久久波多野结衣高潮| 久久99精品国产99久久| 手机看片久久高清国产日韩| 久久99亚洲网美利坚合众国| 国产亚州精品女人久久久久久 | 中文精品久久久久国产网址|