青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

牽著老婆滿街逛

嚴(yán)以律己,寬以待人. 三思而后行.
GMail/GTalk: yanglinbo#google.com;
MSN/Email: tx7do#yahoo.com.cn;
QQ: 3 0 3 3 9 6 9 2 0 .

Linux 同步方法剖析

在學(xué)習(xí) Linux? 的過(guò)程中,您也許接觸過(guò)并發(fā)(concurrency)、臨界段(critical section)和鎖定,但是如何在內(nèi)核中使用這些概念呢?本文討論了 2.6 版內(nèi)核中可用的鎖定機(jī)制,包括原子運(yùn)算符(atomic operator)、自旋鎖(spinlock)、讀/寫鎖(reader/writer lock)和內(nèi)核信號(hào)量(kernel semaphore)。 本文還探討了每種機(jī)制最適合應(yīng)用到哪些地方,以構(gòu)建安全高效的內(nèi)核代碼。

本文討論了 Linux 內(nèi)核中可用的大量同步或鎖定機(jī)制。這些機(jī)制為 2.6.23 版內(nèi)核的許多可用方法提供了應(yīng)用程序接口(API)。但是在深入學(xué)習(xí) API 之前,首先需要明白將要解決的問(wèn)題。

并發(fā)和鎖定

當(dāng)存在并發(fā)特性時(shí),必須使用同步方法。當(dāng)在同一時(shí)間段出現(xiàn)兩個(gè)或更多進(jìn)程并且這些進(jìn)程彼此交互(例如,共享相同的資源)時(shí),就存在并發(fā) 現(xiàn)象。

在單處理器(uniprocessor,UP)主機(jī)上可能發(fā)生并發(fā),在這種主機(jī)中多個(gè)線程共享同一個(gè) CPU 并且搶占(preemption)創(chuàng)建競(jìng)態(tài)條件。搶占 通過(guò)臨時(shí)中斷一個(gè)線程以執(zhí)行另一個(gè)線程的方式來(lái)實(shí)現(xiàn) CPU 共享。競(jìng)態(tài)條件 發(fā)生在兩個(gè)或更多線程操縱一個(gè)共享數(shù)據(jù)項(xiàng)時(shí),其結(jié)果取決于執(zhí)行的時(shí)間。在多處理器(MP)計(jì)算機(jī)中也存在并發(fā),其中每個(gè)處理器中共享相同數(shù)據(jù)的線程同時(shí)執(zhí)行。注意在 MP 情況下存在真正的并行(parallelism),因?yàn)榫€程是同時(shí)執(zhí)行的。而在 UP 情形中,并行是通過(guò)搶占創(chuàng)建的。兩種模式中實(shí)現(xiàn)并發(fā)都較為困難。

Linux 內(nèi)核在兩種模式中都支持并發(fā)。內(nèi)核本身是動(dòng)態(tài)的,而且有許多創(chuàng)建競(jìng)態(tài)條件的方法。Linux 內(nèi)核也支持多處理(multiprocessing),稱為對(duì)稱多處理(SMP)。可以在本文后面的 參考資料 部分學(xué)到更多關(guān)于 SMP 的知識(shí)。

臨界段概念是為解決競(jìng)態(tài)條件問(wèn)題而產(chǎn)生的。一個(gè)臨界段 是一段不允許多路訪問(wèn)的受保護(hù)的代碼。這段代碼可以操縱共享數(shù)據(jù)或共享服務(wù)(例如硬件外圍設(shè)備)。臨界段操作時(shí)堅(jiān)持互斥鎖(mutual exclusion)原則(當(dāng)一個(gè)線程處于臨界段中時(shí),其他所有線程都不能進(jìn)入臨界段)。

臨界段中需要解決的一個(gè)問(wèn)題是死鎖條件。考慮兩個(gè)獨(dú)立的臨界段,各自保護(hù)不同的資源。每個(gè)資源擁有一個(gè)鎖,在本例中稱為 A 和 B。假設(shè)有兩個(gè)線程需要訪問(wèn)這些資源,線程 X 獲取了鎖 A,線程 Y 獲取了鎖 B。當(dāng)這些鎖都被持有時(shí),每個(gè)線程都試圖占有其他線程當(dāng)前持有的鎖(線程 X 想要鎖 B,線程 Y 想要鎖 A)。這時(shí)候線程就被死鎖了,因?yàn)樗鼈兌汲钟幸粋€(gè)鎖而且還想要其他鎖。一個(gè)簡(jiǎn)單的解決方案就是總是按相同次序獲取鎖,從而使其中一個(gè)線程得以完成。還需要其他解決方案檢測(cè)這種情形。表 1 定義了此處用到的一些重要的并發(fā)術(shù)語(yǔ)。


表 1. 并發(fā)中的重要定義
術(shù)語(yǔ) 定義
競(jìng)態(tài)條件 兩個(gè)或更多線程同時(shí)操作資源時(shí)將會(huì)導(dǎo)致不一致的結(jié)果。
臨界段 用于協(xié)調(diào)對(duì)共享資源的訪問(wèn)的代碼段。
互斥鎖 確保對(duì)共享資源進(jìn)行排他訪問(wèn)的軟件特性。
死鎖 由兩個(gè)或更多進(jìn)程和資源鎖導(dǎo)致的一種特殊情形,將會(huì)降低進(jìn)程的工作效率。

 

Linux 同步方法

如果您了解了一些基本理論并且明白了需要解決的問(wèn)題,接下來(lái)將學(xué)習(xí) Linux 支持并發(fā)和互斥鎖的各種方法。在以前,互斥鎖是通過(guò)禁用中斷來(lái)提供的,但是這種形式的鎖定效率比較低(現(xiàn)在在內(nèi)核中仍然存在這種用法)。這種方法也不能進(jìn)行擴(kuò)展,而且不能保證其他處理器上的互斥鎖。

在以下關(guān)于鎖定機(jī)制的討論中,我們首先看一下原子運(yùn)算符,它可以保護(hù)簡(jiǎn)單變量(計(jì)數(shù)器和位掩碼(bitmask))。然后介紹簡(jiǎn)單的自旋鎖和讀/寫鎖,它們構(gòu)成了一個(gè) SMP 架構(gòu)的忙等待鎖(busy-wait lock)覆蓋。最后,我們討論構(gòu)建在原子 API 上的內(nèi)核互斥鎖。

原子操作

Linux 中最簡(jiǎn)單的同步方法就是原子操作。原子 意味著臨界段被包含在 API 函數(shù)中。不需要額外的鎖定,因?yàn)?API 函數(shù)已經(jīng)包含了鎖定。由于 C 不能實(shí)現(xiàn)原子操作,因此 Linux 依靠底層架構(gòu)來(lái)提供這項(xiàng)功能。各種底層架構(gòu)存在很大差異,因此原子函數(shù)的實(shí)現(xiàn)方法也各不相同。一些方法完全通過(guò)匯編語(yǔ)言來(lái)實(shí)現(xiàn),而另一些方法依靠 c 語(yǔ)言并且使用 local_irq_savelocal_irq_restore 禁用中斷。

當(dāng)需要保護(hù)的數(shù)據(jù)非常簡(jiǎn)單時(shí),例如一個(gè)計(jì)數(shù)器,原子運(yùn)算符是種理想的方法。盡管原理簡(jiǎn)單,原子 API 提供了許多針對(duì)不同情形的運(yùn)算符。下面是一個(gè)使用此 API 的示例。

要聲明一個(gè)原子變量(atomic variable),首先聲明一個(gè) atomic_t 類型的變量。這個(gè)結(jié)構(gòu)包含了單個(gè) int 元素。接下來(lái),需確保您的原子變量使用 ATOMIC_INIT 符號(hào)常量進(jìn)行了初始化。 在清單 1 的情形中,原子計(jì)數(shù)器被設(shè)置為 0。也可以使用 atomic_set 在運(yùn)行時(shí)對(duì)原子變量進(jìn)行初始化。


清單 1. 創(chuàng)建和初始化原子變量
atomic_t my_counter ATOMIC_INIT(0);
            ... or ...
            atomic_set( &my_counter, 0 );

原子 API 支持一個(gè)涵蓋許多用例的富函數(shù)集。可以使用 atomic_read 讀取原子變量中的內(nèi)容,也可以使用 atomic_add 為一個(gè)變量添加指定值。最常用的操作是使用 atomic_inc 使變量遞增。也可用減號(hào)運(yùn)算符,它的作用與相加和遞增操作相反。清單 2. 演示了這些函數(shù)。


清單 2. 簡(jiǎn)單的算術(shù)原子函數(shù)
val = atomic_read( &my_counter );
            atomic_add( 1, &my_counter );
            atomic_inc( &my_counter );
            atomic_sub( 1, &my_counter );
            atomic_dec( &my_counter );

該 API 也支持許多其他常用用例,包括 operate-and-test 例程。這些例程允許對(duì)原子變量進(jìn)行操縱和測(cè)試(作為一個(gè)原子操作來(lái)執(zhí)行)。一個(gè)叫做 atomic_add_negative 的特殊函數(shù)被添加到原子變量中,然后當(dāng)結(jié)果值為負(fù)數(shù)時(shí)返回真(true)。這被內(nèi)核中一些依賴于架構(gòu)的信號(hào)量函數(shù)使用。

許多函數(shù)都不返回變量的值,但兩個(gè)函數(shù)除外。它們會(huì)返回結(jié)果值( atomic_add_returnatomic_sub_return),如清單 3所示。


清單 3. Operate-and-test 原子函數(shù)
if (atomic_sub_and_test( 1, &my_counter )) {
            // my_counter is zero
            }
            if (atomic_dec_and_test( &my_counter )) {
            // my_counter is zero
            }
            if (atomic_inc_and_test( &my_counter )) {
            // my_counter is zero
            }
            if (atomic_add_negative( 1, &my_counter )) {
            // my_counter is less than zero
            }
            val = atomic_add_return( 1, &my_counter ));
            val = atomic_sub_return( 1, &my_counter ));

如果您的架構(gòu)支持 64 位長(zhǎng)類型(BITS_PER_LONG 是 64 的),那么可以使用 long_t atomic 操作。可以在 linux/include/asm-generic/atomic.h 中查看可用的長(zhǎng)操作(long operation)。

原子 API 還支持位掩碼(bitmask)操作。跟前面提到的算術(shù)操作不一樣,它只包含設(shè)置和清除操作。許多驅(qū)動(dòng)程序使用這些原子操作,特別是 SCSI。位掩碼原子操作的使用跟算術(shù)操作存在細(xì)微的差別,因?yàn)槠渲兄挥袃蓚€(gè)可用的操作(設(shè)置掩碼和清除掩碼)。使用這些操作前,需要提供一個(gè)值和將要進(jìn)行操作的位掩碼,如清單 4 所示。


清單 4. 位掩碼原子函數(shù)
unsigned long my_bitmask;
            atomic_clear_mask( 0, &my_bitmask );
            atomic_set_mask( (1<<24), &my_bitmask );

自旋鎖

自旋鎖是使用忙等待鎖來(lái)確保互斥鎖的一種特殊方法。如果鎖可用,則獲取鎖,執(zhí)行互斥鎖動(dòng)作,然后釋放鎖。如果鎖不可用,線程將忙等待該鎖,直到其可用為止。忙等待看起來(lái)效率低下,但它實(shí)際上比將線程休眠然后當(dāng)鎖可用時(shí)將其喚醒要快得多。

自旋鎖只在 SMP 系統(tǒng)中才有用,但是因?yàn)槟拇a最終將會(huì)在 SMP 系統(tǒng)上運(yùn)行,將它們添加到 UP 系統(tǒng)是個(gè)明智的做法。

自旋鎖有兩種可用的形式:完全鎖(full lock)和讀寫鎖。 首先看一下完全鎖。

首先通過(guò)一個(gè)簡(jiǎn)單的聲明創(chuàng)建一個(gè)新的自旋鎖。這可以通過(guò)調(diào)用 spin_lock_init 進(jìn)行初始化。清單 5 中顯示的每個(gè)變量都會(huì)實(shí)現(xiàn)相同的結(jié)果。


清單 5. 創(chuàng)建和初始化自旋鎖

spinlock_t my_spinlock = SPIN_LOCK_UNLOCKED;
            ... or ...
            DEFINE_SPINLOCK( my_spinlock );
            ... or ...
            spin_lock_init( &my_spinlock );

 

定義了自旋鎖之后,就可以使用大量的鎖定變量了。每個(gè)變量用于不同的上下文。

清單 6 中顯示了 spin_lockspin_unlock 變量。這是一個(gè)最簡(jiǎn)單的變量,它不會(huì)執(zhí)行中斷禁用,但是包含全部的內(nèi)存壁壘(memory barrier)。這個(gè)變量假定中斷處理程序和該鎖之間沒(méi)有交互。


清單 6. 自旋鎖 lock 和 unlock 函數(shù)

spin_lock( &my_spinlock );
            // critical section
            spin_unlock( &my_spinlock );

 

接下來(lái)是 irqsaveirqrestore 對(duì),如清單 7 所示。spin_lock_irqsave 函數(shù)需要自旋鎖,并且在本地處理器(在 SMP 情形中)上禁用中斷。spin_unlock_irqrestore 函數(shù)釋放自旋鎖,并且(通過(guò) flags 參數(shù))恢復(fù)中斷。


清單 7. 自旋鎖變量,其中禁用了本地 CPU 中斷

spin_lock_irqsave( &my_spinlock, flags );
            // critical section
            spin_unlock_irqrestore( &my_spinlock, flags );

 

spin_lock_irqsave/spin_unlock_irqrestore 的一個(gè)不太安全的變體是 spin_lock_irq/spin_unlock_irq。 我建議不要使用此變體,因?yàn)樗鼤?huì)假設(shè)中斷狀態(tài)。

最后,如果內(nèi)核線程通過(guò) bottom half 方式共享數(shù)據(jù),那么可以使用自旋鎖的另一個(gè)變體。bottom half 方法可以將設(shè)備驅(qū)動(dòng)程序中的工作延遲到中斷處理后執(zhí)行。這種自旋鎖禁用了本地 CPU 上的軟中斷。這可以阻止 softirq、tasklet 和 bottom half 在本地 CPU 上運(yùn)行。這個(gè)變體如清單 8 所示。


清單 8. 自旋鎖函數(shù)實(shí)現(xiàn) bottom-half 交互

spin_lock_bh( &my_spinlock );
            // critical section
            spin_unlock_bh( &my_spinlock );

讀/寫鎖

在許多情形下,對(duì)數(shù)據(jù)的訪問(wèn)是由大量的讀和少量的寫操作來(lái)完成的(讀取數(shù)據(jù)比寫入數(shù)據(jù)更常見(jiàn))。讀/寫鎖的創(chuàng)建就是為了支持這種模型。這個(gè)模型有趣的地方在于允許多個(gè)線程同時(shí)訪問(wèn)相同數(shù)據(jù),但同一時(shí)刻只允許一個(gè)線程寫入數(shù)據(jù)。如果執(zhí)行寫操作的線程持有此鎖,則臨界段不能由其他線程讀取。如果一個(gè)執(zhí)行讀操作的線程持有此鎖,那么多個(gè)讀線程都可以進(jìn)入臨界段。清單 9 演示了這個(gè)模型。


清單 9. 讀/寫自旋鎖函數(shù)
rwlock_t my_rwlock;
            rwlock_init( &my_rwlock );
            write_lock( &my_rwlock );
            // critical section -- can read and write
            write_unlock( &my_rwlock );
            read_lock( &my_rwlock );
            // critical section -- can read only
            read_unlock( &my_rwlock );

根據(jù)對(duì)鎖的需求,還針對(duì) bottom half 和中斷請(qǐng)求(IRQ)對(duì)讀/寫自旋鎖進(jìn)行了修改。顯然,如果您使用的是原版的讀/寫鎖,那么按照標(biāo)準(zhǔn)自旋鎖的用法使用這個(gè)自旋鎖,而不區(qū)分讀線程和寫線程。

內(nèi)核互斥鎖

在內(nèi)核中可以使用互斥鎖來(lái)實(shí)現(xiàn)信號(hào)量行為。內(nèi)核互斥鎖是在原子 API 之上實(shí)現(xiàn)的,但這對(duì)于內(nèi)核用戶是不可見(jiàn)的。互斥鎖很簡(jiǎn)單,但是有一些規(guī)則必須牢記。同一時(shí)間只能有一個(gè)任務(wù)持有互斥鎖,而且只有這個(gè)任務(wù)可以對(duì)互斥鎖進(jìn)行解鎖。互斥鎖不能進(jìn)行遞歸鎖定或解鎖,并且互斥鎖可能不能用于交互上下文。但是互斥鎖比當(dāng)前的內(nèi)核信號(hào)量選項(xiàng)更快,并且更加緊湊,因此如果它們滿足您的需求,那么它們將是您明智的選擇。

可以通過(guò) DEFINE_MUTEX 宏使用一個(gè)操作創(chuàng)建和初始化互斥鎖。這將創(chuàng)建一個(gè)新的互斥鎖并初始化其結(jié)構(gòu)。可以在 ./linux/include/linux/mutex.h 中查看該實(shí)現(xiàn)。

DEFINE_MUTEX( my_mutex );

互斥鎖 API 提供了 5 個(gè)函數(shù):其中 3 個(gè)用于鎖定,一個(gè)用于解鎖,另一個(gè)用于測(cè)試互斥鎖。首先看一下鎖定函數(shù)。在需要立即鎖定以及希望在互斥鎖不可用時(shí)掌握控制的情形下,可以使用第一個(gè)函數(shù) mutex_trylock。該函數(shù)如清單 10 所示。


清單 10. 嘗試使用 mutex_trylock 獲得互斥鎖
ret = mutex_trylock( &my_mutex );
            if (ret != 0) {
            // Got the lock!
            } else {
            // Did not get the lock
            }

如果想等待這個(gè)鎖,可以調(diào)用 mutex_lock。這個(gè)調(diào)用在互斥鎖可用時(shí)返回,否則,在互斥鎖鎖可用之前它將休眠。無(wú)論在哪種情形中,當(dāng)控制被返回時(shí),調(diào)用者將持有互斥鎖。最后,當(dāng)調(diào)用者休眠時(shí)使用 mutex_lock_interruptible。在這種情況下,該函數(shù)可能返回 -EINTR。清單 11 中顯示了這兩種調(diào)用。


清單 11. 鎖定一個(gè)可能處于休眠狀態(tài)的互斥鎖
mutex_lock( &my_mutex );
            // Lock is now held by the caller.
            if (mutex_lock_interruptible( &my_mutex ) != 0)  {
            // Interrupted by a signal, no mutex held
            }

當(dāng)一個(gè)互斥鎖被鎖定后,它必須被解鎖。這是由 mutex_unlock 函數(shù)來(lái)完成的。這個(gè)函數(shù)不能從中斷上下文調(diào)用。最后,可以通過(guò)調(diào)用 mutex_is_locked 檢查互斥鎖的狀態(tài)。這個(gè)調(diào)用實(shí)際上編譯成一個(gè)內(nèi)聯(lián)函數(shù)。如果互斥鎖被持有(鎖定),那么就會(huì)返回 1;否則,返回 0。清單 12 演示了這些函數(shù)。


清單 12. 用 mutex_is_locked 測(cè)試互斥鎖鎖
mutex_unlock( &my_mutex );
            if (mutex_is_locked( &my_mutex ) == 0) {
            // Mutex is unlocked
            }

互斥鎖 API 存在著自身的局限性,因?yàn)樗腔谠?API 的。但是其效率比較高,如果能滿足你的需要,還是可以使用的。

大內(nèi)核鎖(Big kernel lock)

最后看一下大內(nèi)核鎖(BLK)。它在內(nèi)核中的用途越來(lái)越小,但是仍然有一些保留下來(lái)的用法。BKL 使多處理器 Linux 成為可能,但是細(xì)粒度(finer-grained)鎖正在慢慢取代 BKL。BKL 通過(guò) lock_kernelunlock_kernel 函數(shù)提供。要獲得更多信息,請(qǐng)查看 ./linux/lib/kernel_lock.c。

結(jié)束語(yǔ)

Linux 性能非凡,其鎖定方法也一樣。原子鎖不僅提供了一種鎖定機(jī)制,同時(shí)也提供了算術(shù)或 bitwise 操作。自旋鎖提供了一種鎖定機(jī)制(主要應(yīng)用于 SMP),而且讀/寫自旋鎖允許多個(gè)讀線程且僅有一個(gè)寫線程獲得給定的鎖。最后,互斥鎖是一種新的鎖定機(jī)制,提供了一種構(gòu)建在原子之上的簡(jiǎn)單 API。不管你需要什么,Linux 都會(huì)提供一種鎖定方案保護(hù)您的數(shù)據(jù)。

posted on 2008-01-25 11:26 楊粼波 閱讀(268) 評(píng)論(0)  編輯 收藏 引用


只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。
網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問(wèn)   Chat2DB   管理


青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
            一区二区三欧美| 午夜精品一区二区在线观看 | 欧美日韩一区二区精品| 久久久免费av| 美国十次成人| 欧美高清在线| 欧美日韩一区二区视频在线| 欧美色图天堂网| 国产精品久久久| 国产在线不卡| 亚洲国产日本| 亚洲一卡二卡三卡四卡五卡| 午夜视频久久久久久| 久久精品女人| 亚洲国产美女| 亚洲一区二区三区四区在线观看 | 久久亚洲精品一区| 欧美激情综合色| 一区二区三区精品在线| 欧美一级二区| 欧美一区高清| 美女主播一区| 99国产精品视频免费观看| 亚洲视频欧美视频| 久久亚洲精品一区二区| 欧美日一区二区在线观看 | 欧美大片91| 国产精品任我爽爆在线播放| 狠狠色噜噜狠狠色综合久| 99re亚洲国产精品| 久久久久久久综合日本| 欧美a级片一区| 午夜精彩视频在线观看不卡| 欧美成人午夜免费视在线看片| 国产精品久久91| 亚洲精品乱码视频| 久久精品视频在线播放| 亚洲伦理网站| 蜜臀久久99精品久久久画质超高清| 欧美日韩中文字幕综合视频 | 欧美日韩在线看| 在线欧美亚洲| 久久精品一区二区三区不卡| 亚洲黄网站黄| 欧美成人国产| 亚洲国产成人高清精品| 欧美在线观看你懂的| 日韩亚洲不卡在线| 欧美激情精品久久久| 在线播放日韩欧美| 欧美在线视频一区二区三区| 一个色综合导航| 欧美日韩精品二区| 亚洲精品久久久久| 欧美激情中文字幕乱码免费| 久久偷窥视频| 亚洲国产成人91精品| 欧美成人r级一区二区三区| 欧美尤物巨大精品爽| 国产目拍亚洲精品99久久精品| 亚洲私拍自拍| 一区二区三区四区国产精品| 一本色道久久综合亚洲精品婷婷 | 国模私拍一区二区三区| 午夜精品亚洲| 亚洲欧美日韩精品久久亚洲区| 国产精品久在线观看| 亚洲欧美日韩国产另类专区| av成人免费| 国产酒店精品激情| 久久久美女艺术照精彩视频福利播放 | 欧美 日韩 国产一区二区在线视频| 亚洲专区一区| 亚洲精品美女91| 欧美激情视频免费观看| 亚洲七七久久综合桃花剧情介绍| 久久精品中文字幕免费mv| 午夜在线播放视频欧美| 国产精品狠色婷| 亚洲女人天堂av| 欧美一级久久久| 国产综合在线看| 免费不卡在线观看av| 噜噜噜91成人网| 宅男精品视频| 亚洲天堂男人| 国产一区二区在线观看免费播放| 久久综合福利| 欧美成人r级一区二区三区| 亚洲乱码国产乱码精品精天堂| 欧美不卡高清| 欧美日韩一区二区三区免费| 99精品国产热久久91蜜凸| 亚洲欧洲另类| 国产亚洲欧洲997久久综合| 美女黄网久久| 国产精品九九久久久久久久| 久久国产黑丝| 欧美激情亚洲综合一区| 先锋资源久久| 久久裸体视频| 一区二区三区国产| 欧美影院在线播放| 夜夜爽www精品| 久久婷婷激情| 亚洲欧美在线免费观看| 久久―日本道色综合久久| 99精品99| 久久午夜激情| 欧美在线观看一区二区| 欧美裸体一区二区三区| 久久精品综合| 欧美日韩亚洲天堂| 美女脱光内衣内裤视频久久影院 | 老司机成人网| 午夜精品福利视频| 欧美激情一区二区在线 | 亚洲天堂偷拍| 另类天堂视频在线观看| 新狼窝色av性久久久久久| 欧美高清不卡在线| 久久国产精品一区二区三区| 欧美国产精品劲爆| 久久久久久精| 国产乱码精品一区二区三区av | 亚洲在线黄色| 一本色道久久综合精品竹菊 | 亚洲夜间福利| 最新国产成人av网站网址麻豆| 亚洲午夜av电影| 在线一区亚洲| 欧美日韩国产二区| 亚洲大胆视频| 在线成人av.com| 午夜久久久久| 欧美一区二区日韩| 欧美日韩在线直播| 99视频国产精品免费观看| 99国产精品久久久久久久久久 | 久久久久成人网| 欧美在线看片a免费观看| 欧美特黄一区| 亚洲社区在线观看| 亚洲一级一区| 国产精品高清网站| 中文日韩在线| 亚洲综合电影一区二区三区| 欧美日本一道本在线视频| 欧美成人一区二免费视频软件| 国内精品伊人久久久久av一坑| 一本一本a久久| 亚洲欧美www| 国产日韩欧美一区二区三区四区| 亚洲五月六月| 久久久噜噜噜久久狠狠50岁| 国内久久婷婷综合| 免费欧美在线视频| 亚洲人成亚洲人成在线观看| 亚洲理论在线观看| 欧美午夜精品久久久久久浪潮| 99这里只有久久精品视频| 亚洲小说春色综合另类电影| 国产精品极品美女粉嫩高清在线| 一本大道久久a久久精二百| 亚洲综合日韩| 国产一区激情| 欧美成人免费全部| 中国日韩欧美久久久久久久久| 亚洲在线日韩| 国产亚洲午夜| 玖玖玖国产精品| 亚洲美女区一区| 欧美一区在线直播| 在线看无码的免费网站| 久久综合网络一区二区| av不卡免费看| 久久综合伊人77777蜜臀| 亚洲激情视频网站| 国产精品人人爽人人做我的可爱| 久久aⅴ乱码一区二区三区| 亚洲第一视频网站| 香蕉久久国产| 亚洲人成网站精品片在线观看| 国产精品v片在线观看不卡| 久久精品99| 夜夜爽av福利精品导航 | 久久精品三级| 一本一道久久综合狠狠老精东影业| 欧美在线国产精品| 亚洲美女区一区| 国产在线精品二区| 欧美人与性动交cc0o| 老司机久久99久久精品播放免费| 亚洲特黄一级片| 亚洲高清在线| 欧美中文日韩| 一区二区三区免费看| 精品91视频| 国产精品中文字幕在线观看| 牛牛影视久久网|