午夜视频免费看_日韩三级电影网站_国产精品久久一级_亚洲一级在线播放_人妻体内射精一区二区三区_91夜夜揉人人捏人人添红杏_91福利在线导航_国产又粗又猛又黄又爽无遮挡_欧美日韩一区在线播放_中文字幕一区二区三区四区不卡 _日日夜夜精品视频免费观看_欧美韩日一区二区三区

主頁 > 知識庫 > Python并發編程實例教程之線程的玩法

Python并發編程實例教程之線程的玩法

熱門標簽:高德地圖標注是免費的嗎 地圖標注視頻廣告 無錫客服外呼系統一般多少錢 洪澤縣地圖標注 梅州外呼業務系統 北京電信外呼系統靠譜嗎 大連crm外呼系統 老人電話機器人 百度地圖標注位置怎么修改

一、線程基礎以及守護進程

線程是CPU調度的最小單位

全局解釋器鎖

全局解釋器鎖GIL(global interpreter lock)

全局解釋器鎖的出現主要是為了完成垃圾回收機制的回收機制,對不同線程的引用計數的變化記錄的更加精準。

全局解釋器鎖導致了同一個進程中的多個線程只能有一個線程真正被CPU執行。

GIL鎖每執行700條指令才會進行一次(輪轉)切換(從一個線程切換到另外一個線程)

節省的是IO操作(不占用CPU)的時間,而不是CPU計算的時間,因為CPU的計算速度非常快,大多數情況下,我們沒有辦法把一條進程中所有的IO操作都規避掉。

threading模塊

import time
from threading import Thread, current_thread, enumerate, active_count


def func(i):
    print('start%s' % i, current_thread().ident)  # 函數中獲取當前線程id
    time.sleep(1)
    print('end%s' % i)


if __name__ == '__main__':
    t1 = []
    for i in range(3):
        t = Thread(target=func, args=(i,))
        t.start()
        print(t.ident)  # 查看當前線程id
        t1.append(t)
    print(enumerate(), active_count())
    for t in t1:
        t.join()
print('所有線程執行完畢')

線程是不能從外部強制終止(terminate),所有的子線程只能是自己執行完代碼之后就關閉。

current_thread 獲取當前的線程對象

current_thread().ident 或者 線程對象.ident 獲取當前線程id。

enumerate返回一個列表,存儲了所有活著的線程對象,包括主線程。

active_count返回一個數字,存儲了所有活著的線程個數。

【注意】enumerate導入之后,會和內置函數enumerate重名,需要做特殊的處理

  • from threading import enumerate as en
  • import threading
    threading.enumerate()

面向對象方式開啟一個線程

from threading import Thread


class MyThread(Thread):
    def __init__(self, a, b):
        super(MyThread, self).__init__()
        self.a = a
        self.b = b

    def run(self):
        print(self.ident)


t = MyThread(1, 3)
t.start()  # 開啟線程,才在線程中執行run方法
print(t.ident)

線程之間的數據是共享的

from threading import Thread

n = 100


def func():
    global n
    n -= 1


t_li = []
for i in range(100):
    t = Thread(target=func)
    t.start()
    t_li.append(t)
for t in t_li:
    t.join()
print(n)

結果是:0

守護線程

  • 主線程會等待子線程結束之后才結束,為什么?

因為主線程結束,進程就會結束。

  • 守護線程隨著主線程的結束而結束
  • 守護進程會隨著主進程的代碼結束而結束,如果主進程代碼之后還有其他子進程在運行,守護進程不守護。
  • 守護線程會隨著主線程的結束而結束,如果主線程代碼結束之后還有其他子線程在運行,守護線程也守護。
import time
from threading import Thread


def son():
    while True:
        print('in son')
        time.sleep(1)


def son2():
    for i in range(3):
        print('in son2...')
        time.sleep(1)


# flag a
t = Thread(target=son)
t.daemon = True
t.start()
# flag b a-->b用時0s
Thread(target=son2).start()

為什么守護線程會在主線程的代碼結束之后繼續守護其他子線程?

答:因為守護進程和守護線程的結束原理不同。守護進程需要主進程來回收資源,守護線程是隨著主線程的結束而結束,其他子線程–>主線程結束–>主進程結束–>整個進程中所有的資源都被回收,守護線程也會被回收。

二、線程鎖(互斥鎖)

線程之間也存在數據不安全

import dis

a = 0


def func():
    global a
    a += 1


dis.dis(func)  # 得到func方法中的代碼翻譯成CPU指令
"""
結果
0 LOAD_GLOBAL              0 (a)
2 LOAD_CONST               1 (1)
4 INPLACE_ADD
6 STORE_GLOBAL             0 (a)
8 LOAD_CONST               0 (None)
10 RETURN_VALUE
"""

+=、-=、*=、/=、while、if、帶返回值的方法(都是先計算后賦值,前提要涉及到全局變量或靜態變量) 等都是數據不安全的,append、pop、queue、logging模塊等都是數據安全的。

列表中的方法或者字典中的方法去操作全局變量的時候,數據是安全的。

只有一個線程,永遠不會出現線程不安全現象。

采用加鎖的方式來保證數據安全。

from threading import Thread, Lock

n = 0


def add(lock):
    for i in range(500000):
        global n
        with lock:
            n += 1


def sub(lock):
    for i in range(500000):
        global n
        with lock:
            n -= 1


t_li = []
lock = Lock()
for i in range(2):
    t1 = Thread(target=add, args=(lock,))
    t1.start()
    t2 = Thread(target=sub, args=(lock,))
    t2.start()
    t_li.append(t1)
    t_li.append(t2)
for t in t_li:
    t.join()
print(n)

線程安全的單例模式

import time
from threading import Thread, Lock


class A:
    __instance = None
    lock = Lock()

    def __new__(cls, *args, **kwargs):
        with cls.lock:
            if not cls.__instance:
                time.sleep(0.00001)
                cls.__instance = super().__new__(cls)
        return cls.__instance


def func():
    a = A()
    print(a)


for i in range(10):
    Thread(target=func).start()

不用考慮加鎖的小技巧

  • 不要操作全局變量
  • 不要在類中操作靜態變量

因為多個線程同時操作全局變量/靜態變量,會產生數據不安全現象。

三、線程鎖(遞歸鎖)

from threading import Lock, RLock

# Lock 互斥鎖
# RLock 遞歸(recursion)鎖

l = Lock()
l.acquire()
print('希望被鎖住的代碼')
l.release()

rl = RLock()  # 在同一個線程中可以被acquire多次
rl.acquire()
rl.acquire()
rl.acquire()
print('希望被鎖住的代碼')
rl.release()

from threading import Thread, RLock


def func(i, lock):
    lock.acquire()
    lock.acquire()
    print(i, ':start')
    lock.release()
    lock.release()
    print(i, ':end')


lock = RLock()
for i in range(5):
    Thread(target=func, args=(i, lock)).start()

互斥鎖與遞歸鎖

遞歸鎖在同一個線程中可以被acquire多次,而互斥鎖不行

互斥鎖效率高,遞歸鎖效率相對低

多把互斥鎖容易產生死鎖現象,遞歸鎖可以快速解決死鎖

四、死鎖

死鎖:指兩個或兩個以上的進程或線程在執行過程中,因爭奪資源而造成的一種互相等待的現象。

死鎖現象是怎么產生的?

答:有多把鎖,并且在多個線程中交叉使用。與互斥鎖、遞歸鎖無關,都會發生死鎖。如果是互斥鎖,出現了死鎖現象,最快速的解決方案是把所有的互斥鎖都改成一把遞歸鎖(noodle_lock = fork_lock = RLock()),程序的效率會降低。

from threading import Thread, Lock
import time
noodle_lock = Lock()
fork_lock = Lock()


def eat1(name):
    noodle_lock.acquire()
    print(name, '搶到面了')
    fork_lock.acquire()
    print(name, '搶到叉子了')
    print(name, '吃面')
    time.sleep(0.0001)
    fork_lock.release()
    print(name, '放下叉子了')
    noodle_lock.release()
    print(name, '放下面了')


def eat2(name):
    fork_lock.acquire()
    print(name, '搶到叉子了')
    noodle_lock.acquire()
    print(name, '搶到面了')
    print(name, '吃面')
    noodle_lock.release()
    print(name, '放下面了')
    fork_lock.release()
    print(name, '放下叉子了')


Thread(target=eat1, args=('lucy',)).start()
Thread(target=eat2, args=('jack',)).start()
Thread(target=eat1, args=('rose',)).start()
Thread(target=eat2, args=('disen',)).start()

五、隊列

隊列:線程之間數據安全的容器

線程隊列:數據安全,先進先出

原理:加鎖 + 鏈表

Queue

fifo 先進先出的隊列

get和put

import queue


q = queue.Queue(3)  # fifo 先進先出的隊列

q.put(1)
q.put(2)
print(q.get())
print(q.get())

1
2

get_nowait

import queue

# from queue import Empty  # 不是內置的錯誤類型,而是queue模塊中的錯誤
q = queue.Queue()  # fifo 先進先出的隊列
try:
    q.get_nowait()
except queue.Empty:
    pass
print('隊列為空,繼續執行其他代碼')

put_nowait

用的很少,因為隊列滿時,拋異常,數據放不進去,丟失了。

LifoQueue

后進先出的隊列,也就是棧。last in first out

from queue import LifoQueue
lq = LifoQueue()
lq.put(1)
lq.put(2)
print(lq.get())
print(lq.get())

2
1

PriorityQueue

優先級隊列,按照放入數據的第一位數值從小到大輸出

from queue import PriorityQueue

priq = PriorityQueue()
priq.put((2, 'lucy'))
priq.put((0, 'rose'))
priq.put((1, 'jack'))
print(priq.get())
print(priq.get())
print(priq.get())

(0, 'rose')
(1, 'jack')
(2, 'lucy')

三種隊列使用場景

先進先出:用于處理服務類任務(買票任務)

后進先出:算法中用的比較多

優先級隊列:比如,VIP制度,VIP用戶優先;

六、相關面試題

請聊聊進程隊列的特點和實現原理
特點:實現進程之間的通信;數據安全;先進先出。

實現原理:基于管道 + 鎖 實現的,管道是基于文件級別的socket + pickle 實現的。

你了解生產者消費者模型嗎,如何實現
了解

為什么了解?工作經驗

 采集圖片/爬取音樂:由于要爬取大量的數據,想提高爬取效率

 有用過一個生產者消費者模型,這個模型是我自己寫的,消息中間件,用的是xxx(redis),我獲取網頁的過程作為生產者,分析網頁,獲取所有歌曲歌曲鏈接的過程作為消費者。

 自己寫監控,或者是自己寫郵件報警系統,監控程序作為生產者,一旦發現有問題的程序,就需要把要發送的郵件信息交給消息中間件redis,消費者就從中間件中取值,然后來處理發郵件的邏輯。

什么時候用過?

 項目 或者 例子,結合上面一起

在python中實現生產者消費者模型可以用哪些機制

 消息中間件

 celery(分布式框架):定時發短信的任務

從你的角度說說進程在計算機中扮演什么角色

進程用來管理一個運行中的程序的資源,是資源分配的最小單位

進程與進程之間內存是隔離的

進程是由操作系統負責調度的,并且多個進程之間是一種競爭關系,所以我們應該對進程的三狀態時刻關注,盡量減少進程中的IO操作,或者在進程里面開線程來規避IO,讓我們寫的程序在運行的時候能夠更多的占用CPU資源。

為什么線程之間的數據不安全
線程之間數據共享

多線程的情況下,

 如果在計算某一個變量的時候,還要進行賦值操作,這個過程不是由一條完整的CPU指令完成的;

 如果在判斷某個bool表達式之后,再做某些操作,這個過程也不是由一條完整的CPU指令完成的;

 在中間發生了GIL鎖的切換(時間片的輪轉),可能會導致數據不安全。

讀程序,請確認執行到最后number的長度是否一定為 1

import threading
import time

# loop = 1E7  # 10000000.
loop = int(1E7)  # 10000000


def _add(loop: int = 1):
    global numbers
    for _ in range(loop):
        numbers.append(0)


def _sub(loop: int = 1):
    global numbers
    for _ in range(loop):
        while not numbers:
            time.sleep(1E-8)
        numbers.pop()


numbers = [0]
ta = threading.Thread(target=_add, args=(loop,))
ts = threading.Thread(target=_sub, args=(loop,))
# ts1 = threading.Thread(target=_sub, args=(loop,))

ta.start()
ts.start()
# ts1.start()

ta.join()
ts.join()
# ts1.join()

因為只開啟了一個進行pop操作的線程,如果開啟多個pop操作的線程,必須在while前面加鎖,因為可能有兩個線程,一個執行了while not numbers,發生了GIL的切換,另外一個線程執行完了代碼,numbers剛好沒有了數據,導致結果一個pop成功,一個pop不成功。

所以number長度一定為1,如果把注釋去了,不一定為1

讀程序,請確認執行到最后number的長度是否一定為 1

import threading
import time

loop = int(1E7)


def _add(loop: int = 1):
    global numbers
    for _ in range(loop):
        numbers.append(0)


def _sub(loop: int = 1):
    global numbers
    for _ in range(loop):
        while not numbers:
            time.sleep(1E-8)
        numbers.pop()


numbers = [0]
ta = threading.Thread(target=_add, args=(loop,))
ts = threading.Thread(target=_sub, args=(loop,))

ta.start()
ta.join()
ts.start()
ts.join()

一定為1,因為是同步的。

讀程序,請確認執行到最后number是否一定為 0

import threading

loop = int(1E7)


def _add(loop: int = 1):
    global numbers
    for _ in range(loop):
        numbers += 1


def _sub(loop: int = 1):
    global numbers
    for _ in range(loop):
        numbers -= 1


numbers = 0
ta = threading.Thread(target=_add, args=(loop,))
ts = threading.Thread(target=_sub, args=(loop,))

ta.start()
ta.join()
ts.start()
ts.join()

一定等于0,因為是同步的。

讀程序,請確認執行到最后number是否一定為 0

import threading

loop = int(1E7)


def _add(loop: int = 1):
    global numbers
    for _ in range(loop):
        numbers += 1


def _sub(loop: int = 1):
    global numbers
    for _ in range(loop):
        numbers -= 1


numbers = 0
ta = threading.Thread(target=_add, args=(loop,))
ts = threading.Thread(target=_sub, args=(loop,))

ta.start()
ts.start()
ta.join()
ts.join()

不一定為0,因為是異步的且存在 += 操作

七、判斷數據是否安全

是否數據共享,是同步還是異步(數據共享并且異步的情況下)

  • +=、-=、*=、/=、a = 計算之后賦值給變量
  • if、while 條件,這兩個判斷是由多個線程完成的

這兩種情況下,數據不安全。

八、進程池 線程池

以前,有多少個任務就開多少個進程或線程。

什么是池

要在程序開始的時候,還沒有提交任務,先創建幾個線程或者進程,放在一個池子里,這就是池

為什么要用池

如果先開好進程/線程,那么有任務之后就可以直接使用這個池中的數據了;并且開好的進程/線程會一直存在在池中,可以被多個任務反復利用,這樣極大的減少了開啟/關閉/調度進程/調度線程的時間開銷。

池中的線程/進程個數控制了操作系統需要調用的任務個數,控制池中的單位,有利于提高操作系統的效率,減輕操作系統的負擔。

from concurrent.futures import ThreadPoolExecutor, ProcessPoolExecutor

# threading模塊 沒有提供池
# multiprocessing模塊 仿照threading增加了Pool(逐漸被淘汰)
# concurrent.futures模塊 線程池,進程池都能夠用相似的方式開啟/使用
ThreadPoolExecutor()  # 參數代表開啟多少個線程,線程的個數一般起cpu個數*4(或者*5)
ProcessPoolExecutor()  # 參數代表開啟多少個進程,進程的個數一般起cpu個數+1

創建線程池并提交任務

from concurrent.futures import ThreadPoolExecutor
from threading import current_thread
import time


def func(a, b):
    print(current_thread().ident, a, b)
    time.sleep(1)


tp = ThreadPoolExecutor(4)  # 創建線程池對象
for i in range(20):
    # tp.submit(func, i, i + 1)
    # 向池中提交任務
    tp.submit(func, a=i, b=i + 1)  # 位置傳參,關鍵字傳參都可以

創建進程池并提交任務

from concurrent.futures import ProcessPoolExecutor
import os
import time


def func(a, b):
    print(os.getpid(), 'start', a, b)
    time.sleep(1)
    print(os.getpid(), 'end', a, b)


if __name__ == '__main__':
    tp = ProcessPoolExecutor(4)  # 創建進程池對象
    for i in range(20):
        # tp.submit(func, i, i + 1)
        # 向池中提交任務
        tp.submit(func, a=i, b=i + 1)  # 位置傳參,關鍵字傳參都可以

獲取任務結果

from concurrent.futures import ProcessPoolExecutor
import os
import time


def func(a, b):
    print(os.getpid(), 'start', a, b)
    time.sleep(1)
    print(os.getpid(), 'end', a, b)
    return a * b


if __name__ == '__main__':
    tp = ProcessPoolExecutor(4)  # 創建進程池對象
    future_d = {}
    for i in range(20):  # 異步非阻塞的
        ret = tp.submit(func, a=i, b=i + 1)  # future未來對象
        # print(ret)  # Future at 0x1ad918e1148 state=running>
        # print(ret.result())  # 這樣需要等待,同步的
        future_d[i] = ret
    for key in future_d:  # 同步阻塞的
        print(key, future_d[key].result())

tp對象的map

map 只適合傳遞簡單的參數,并且必須是一個可迭代的類型

from concurrent.futures import ProcessPoolExecutor
import os
import time


def func(a):
    print(os.getpid(), 'start', a[0], a[1])
    time.sleep(1)
    print(os.getpid(), 'end', a[0], a[1])
    return a[0] * a[1]


if __name__ == '__main__':
    tp = ProcessPoolExecutor(4)
    ret = tp.map(func, ((i, i + 1) for i in range(20)))  # 一般函數只接收一個參數,要想傳入多個,使用元組方式
    for r in ret:
        print(r)

回調函數

當有一個結果需要進行處理時,都會綁定一個回調函數來處理,除非是得到所有結果之后才做處理,我們使用 把結果存入列表 遍歷列表 的方式。

回調函數效率最高的。

from concurrent.futures import ThreadPoolExecutor
from threading import current_thread
import time


def func(a, b):
    print(current_thread().ident, 'start', a, b)
    time.sleep(1)
    print(current_thread().ident, 'end', a)
    return a * b


if __name__ == '__main__':
    tp = ThreadPoolExecutor(4)
    future_d = {}
    for i in range(20):  # 異步非阻塞的
        ret = tp.submit(func, a=i, b=i + 1)
        future_d[i] = ret
    for key in future_d:  # 同步阻塞的
        print(key, future_d[key].result())

上述代碼,打印結果是按照順序(0,1,2,3……),并不是誰先結束就打印誰。

使用回調函數以后,誰先執行完就打印誰,代碼如下:

from concurrent.futures import ThreadPoolExecutor
from threading import current_thread
import time


def func(a, b):
    print(current_thread().ident, 'start', a, b)
    time.sleep(1)
    print(current_thread().ident, 'end', a)
    return a, a * b


def print_func(ret):  # 異步阻塞 每個任務都是各自阻塞各自,誰先執行完誰先打印
    print(ret.result())


if __name__ == '__main__':
    tp = ThreadPoolExecutor(4)
    for i in range(20):  # 異步非阻塞的
        ret = tp.submit(func, a=i, b=i + 1)  # [ret0, ret1, ..., ret19]
        ret.add_done_callback(print_func)  # 異步阻塞 [print_func, print_func,...,print_func]
        # 回調機制
        # 回調函數 給ret對象綁定一個回調函數,等待ret對應的任務有了結果之后立即調用print_func函數
        # 就可以對結果立即進行處理,而不用按照順序接收結果處理結果

ret這個任務會在執行完畢的瞬間立即觸發print_func函數,并且把任務的返回值對象傳遞到print_func做參數。

回調函數的例子

from concurrent.futures import ThreadPoolExecutor
import requests


def get_page(url):  # 訪問網頁,獲取網頁源代碼,用線程池中的線程來操作
    respone = requests.get(url)
    if respone.status_code == 200:
        return {'url': url, 'text': respone.text}


def parse_page(res):  # 獲取到字典結果之后,計算網頁源代碼的長度,把'https://www.baidu.com : 長度值'寫到文件里,線程任務執行完畢之后綁定回調函數
    res = res.result()
    parse_res = 'url:%s> size:[%s]\n' % (res['url'], len(res['text']))
    with open('db.txt', 'a') as f:
        f.write(parse_res)


if __name__ == '__main__':
    urls = [
        'https://www.baidu.com',
        'https://www.python.org',
        'https://www.openstack.org',
        'https://www.tencent.com/zh-cn',
        'http://www.sina.com.cn/'
    ]
    tp = ThreadPoolExecutor(4)
    for url in urls:
        ret = tp.submit(get_page, url)
        ret.add_done_callback(parse_page)  # 誰先回來誰就先把結果寫進文件

# 不用回調函數:
    # 按照順序獲取網頁,baidu python openstack tencent sina
    # 也只能按照順序寫
# 用上了回調函數
    # 按照順序獲取網頁,baidu python openstack tencent sina
    # 哪一個網頁先返回結果,就先執行哪個網頁對應的回調函數(parse_page)

進程池線程池的應用場景

進程池:

場景:高計算的場景,沒有IO操作(沒有文件操作,沒有數據庫操作,沒有網絡操作,沒有input);

進程的個數:[cpu_count*1, cpu_count*2]

線程池:
場景:爬蟲

線程的個數:一般根據IO的比例定制,cpu_count*5

總結

到此這篇關于Python并發編程實例教程之線程的文章就介紹到這了,更多相關Python并發編程線程內容請搜索腳本之家以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持腳本之家!

您可能感興趣的文章:
  • Python控制多進程與多線程并發數總結
  • python實現多線程的方式及多條命令并發執行
  • python并發編程之多進程、多線程、異步和協程詳解
  • python多線程并發實例及其優化
  • Python多進程并發與多線程并發編程實例總結
  • python多線程并發及測試框架案例
  • 詳解Python并發編程之創建多線程的幾種方法

標簽:洛陽 泉州 岳陽 清遠 怒江 安慶 長春 吉林

巨人網絡通訊聲明:本文標題《Python并發編程實例教程之線程的玩法》,本文關鍵詞  Python,并發,編程,實例,教程,;如發現本文內容存在版權問題,煩請提供相關信息告之我們,我們將及時溝通與處理。本站內容系統采集于網絡,涉及言論、版權與本站無關。
  • 相關文章
  • 下面列出與本文章《Python并發編程實例教程之線程的玩法》相關的同類信息!
  • 本頁收集關于Python并發編程實例教程之線程的玩法的相關信息資訊供網民參考!
  • 推薦文章
    欧美大片一区二区| 亚洲精品一区二区三区蜜桃| 成人精品视频久久久久| 99久久综合99久久综合网站| 欧美午夜精品久久久久免费视| 国产亚洲精品福利| 精品久久久久久中文字幕2017| 亚洲婷婷国产精品电影人久久| 成人短视频在线看| 亚洲一区二区中文在线| 91视频青青草| 欧美中文字幕在线观看| 成人国产精品视频| 欧美成人福利在线观看| 久久久亚洲综合| 精品国产一二区| 欧美激情国产精品| 狠狠色狠狠色综合日日91app| 日韩视频一二三| 99热这里只有精品1| 444亚洲人体| 高清视频一区二区| 蜜桃传媒视频麻豆一区| 老司机一区二区| www.cao超碰| 欧美精品xxx| 五月天色婷婷丁香| 欧美激情视频网址| 久久久久久久福利| 国产精品99久久久久久久久久久久| 国产iv一区二区三区| 高清中文字幕mv的电影| 亚洲a∨日韩av高清在线观看| 欧美一区二区三区视频| 成人中文字幕电影| 中文字幕电影av| 亚洲一区二区三区加勒比| 精品视频一区二区不卡| 精品国产乱码一区二区| 999国产视频| 亚洲美女免费在线| 久久免费视频99| 国产美女精品视频免费观看| 久久99久久精品| 免费男同深夜夜行网站| 国产成人在线视频| 欧美日韩另类一区| 国产富婆一级全黄大片| 国产1区2区3区中文字幕| 色系网站成人免费| 91小视频在线播放| 91精品国产91久久久久久吃药| 成人精品视频一区二区三区尤物| 性久久久久久久久久久| 奇米影视亚洲狠狠色| 日本欧美一区二区三区| 91猫先生在线| 亚洲国产精品va| 九九免费精品视频| 欧美激情欧美狂野欧美精品| 99久久国产综合色|国产精品| 精品在线视频免费观看| 欧美精品欧美精品| 91精品国产91综合久久蜜臀| 99久久精品国产一区二区成人| 欧美一区二区色| 亚洲男人的天堂一区二区| 国语对白做受69按摩| 免费在线观看的毛片| 日韩av色在线| 欧美在线你懂得| 国产视频一区二区三区四区五区| 国产麻豆日韩| 在线观看三级视频欧美| 中文字幕在线网站| 国产精品一区二区三区毛片淫片| 久久久精品人体av艺术| 久久久久久久国产视频| 大陆av在线播放| 欧美国产欧美亚洲国产日韩mv天天看完整 | 欧美成人黄色网| 国产成人一区二区在线| 亚洲综合偷拍欧美一区色| 夜夜嗨aⅴ一区二区三区| 中国av免费看| 日韩精品综合在线| 久久久www免费人成黑人精品| 韩国精品久久久999| 欧美性xxxxxx| 丁香亚洲综合激情啪啪综合| 久久免费在线观看视频| 一区二区三区偷拍| 欧洲国产伦久久久久久久| 亚洲精品久久久狠狠狠爱| av在线免费看片| 国产成人精品电影| 国产精品久久久久一区| 国产无码精品视频| 日本爱爱免费视频| 国产精品一区视频网站| 国产亚洲欧洲高清| 2欧美一区二区三区在线观看视频 337p粉嫩大胆噜噜噜噜噜91av | 免费成人黄色大片| 97超级碰在线看视频免费在线看 | 超碰超碰在线观看| 亚洲精品成人久久电影| 久久国产欧美日韩精品| av2014天堂网| 97视频在线观看视频免费视频 | 久久五月天色综合| 欧美日韩国产精选| 日韩va亚洲va欧美va久久| 日韩精品aaa| 国产精品综合不卡av| 亚洲一区二区三区国产| 欧美熟女一区二区| 国产精品久久久久久久99| 国产内射老熟女aaaa| 亚洲伊人第一页| 色播久久人人爽人人爽人人片视av| 日韩精品在线免费观看视频| 欧美三级在线视频| 国产精品嫩草影院com| 亚洲国产高清不卡| 久久精品午夜| 国产农村老头老太视频| 国产交换配乱淫视频免费| 欧美精品成人网| 亚洲xxxx视频| 国产午夜精品美女视频明星a级| 国产黄人亚洲片| 看黄色一级大片| 亚洲这里只有精品| 视频一区视频二区视频| 欧美一区二区三区四区视频| 男女性色大片免费观看一区二区| 2017亚洲天堂| 激情综合激情五月| 超碰网在线观看| 国产精品嫩草影院久久久| 在线综合+亚洲+欧美中文字幕| 国产亚洲视频系列| 国产精品300页| 亚洲高清视频一区| 久久精品人人做人人爽| 欧美视频一区二区在线观看| 国产成人精品三级| www.色精品| 国产乱一区二区| 视频一区中文字幕| 亚洲免费黄色片| 国产偷拍一区二区| 少妇一级淫片日本| www.av欧美| 无码无遮挡又大又爽又黄的视频| 性欧美在线看片a免费观看| 精品国产3级a| 亚洲欧美自拍偷拍| 日av在线不卡| 97人妻天天摸天天爽天天| 国产精品久久久久7777婷婷| 欧美一区午夜精品| 在线播放中文字幕一区| 在线国产亚洲欧美| 中文字幕一区二区不卡| 成人午夜福利视频| 精品人妻伦九区久久aaa片| 日韩av一卡二卡三卡| 97超碰蝌蚪网人人做人人爽| 日韩欧美成人一区二区| 亚洲成人一区在线| 亚洲欧美日韩久久精品| 亚洲在线视频免费观看| 精品久久久中文| 天天综合天天做天天综合| 色先锋久久av资源部| 欧美视频免费在线| 欧美性xxxxx| 一区二区国产盗摄色噜噜| 91美女视频网站| 黄色片网站免费在线观看| 男人操女人的视频网站| 99国产精品免费视频| 亚洲成色www.777999| 亚洲一区三区视频在线观看| 欧美一区在线直播| 精品国产精品一区二区夜夜嗨| 欧美剧情电影在线观看完整版免费励志电影 | 在线视频 中文字幕| 精品国产av无码| 小日子的在线观看免费第8集| 欧美资源在线观看| 日韩在线不卡视频| 亚洲人在线视频| 欧美变态口味重另类| 91精品国产色综合久久不卡蜜臀 | 国产精品福利网站| 国产精品伦子伦免费视频| 国产精品一级久久久| 99久久精品免费看国产四区| 午夜精品久久久久久久久久久久| 色偷偷9999www| 欧美精品丝袜中出| 欧洲一区在线观看| 欧美日韩国产精品| 亚洲天堂福利av| 久久精品国产亚洲一区二区三区 | 3d动漫精品啪啪一区二区三区免费 | 久久久999精品| 久久久精品免费| 久久全球大尺度高清视频| 国产精品日韩专区| 国产日韩中文在线| 国产日韩换脸av一区在线观看| 欧美顶级少妇做爰| 国产精品久久久久毛片软件| 国产精品电影院| 99精品欧美一区二区蜜桃免费| 日本一区二区视频在线观看| 依依成人综合视频| 亚洲福利一区二区| 日韩av在线网| 欧美老女人xx| 99伊人久久| 久久久免费看| 99re视频| 品久久久久久久久久96高清| 成人免费自拍视频| 国产精品亚洲一区二区三区| 欧美大学生性色视频| 久久久久久久久久国产精品| 日韩精品免费在线视频观看| 色哦色哦哦色天天综合| 亚洲一区视频在线| 在线观看一区日韩| 亚洲国产97在线精品一区| 中文字幕不卡在线视频极品| 亚洲国产精品久久精品怡红院 | 精品亚洲一区二区三区在线观看| 91精品国产91久久久久久一区二区 | 五月天色婷婷丁香| 精品无码人妻一区二区三区品| 少妇人妻一区二区| 亚洲欧洲日韩综合一区二区| 欧美日韩一区二区三区高清| 精品国产不卡一区二区三区| 久久精品国产2020观看福利| 久久久久久久久久久免费| 国a精品视频大全| 国产精品爱啪在线线免费观看| 亚洲成人av在线| 亚洲欧美制服综合另类| 久久久成人av| 91精品91久久久久久| 人妖精品videosex性欧美| 久久影院资源网| 久久久精品免费视频| 免费av一区二区| 欧美一级片久久久久久久| 97超级碰碰| 国产69精品久久久久999小说| 波多野结衣家庭教师视频| av天堂永久资源网| 亚洲精品一二三四五区| 欧美在线一级片| 亚州精品一二三区| 黄www在线观看| 韩国三级在线看| 99久久久无码国产精品不卡| 日韩综合在线观看| 久久99精品久久久久婷婷| 婷婷一区二区三区| 久久婷婷国产麻豆91天堂| 欧美福利精品| 日本一区二区免费视频| 日本五十熟hd丰满| 日本波多野结衣在线| 99久久精品国产导航| 亚洲国产精品成人久久综合一区 | www.av视频| 影音先锋在线国产| 怡春院在线视频| 久久久精品网| 成人午夜在线免费| 久久久久久一级片| 亚洲免费在线观看| 欧美一级爆毛片| 欧美激情视频一区二区| 视频一区国产精品| 人妻巨大乳一二三区| 精品黑人一区二区三区观看时间| 欧美国产在线看| 国产精品玖玖玖| 国产一区激情在线| 日本一不卡视频| 欧美极品aⅴ影院| 在线观看网站黄不卡| 亚洲天堂第一页| 国产欧美日韩一区二区三区| 亚洲一区二区图片| 国产美女免费视频| 18欧美亚洲精品| 欧美成人午夜免费视在线看片| 99精品视频网站| 欧美色视频一区二区三区在线观看| 亚洲乱码精品久久久久..| 国产日韩欧美综合在线| 日韩av综合中文字幕| 久久久天堂国产精品女人| 久久久精品动漫| 日韩精品久久一区二区| 97超碰在线资源| 亚洲一区中文字幕永久在线| 青青草91视频| 自拍偷在线精品自拍偷无码专区| 日韩精品视频观看| 欧美福利视频在线| 成人h视频在线| 中文字幕精品一区日韩| 五月婷婷狠狠操| 国产乱国产乱老熟300| 国产91精品一区二区麻豆亚洲| 在线免费av一区| 91精品国产91久久久久久吃药| 久久草.com| 国产男女激情视频| 福利一区二区三区四区| 另类欧美日韩国产在线| 国产成人av网站| 国产精品嫩草影院com| 日韩精品在线一区| 国产精品久久久久久久app| 国产精品久久国产| 日本免费一二三区| 国产精品网曝门| 久久亚洲精品成人| 亚洲最大色综合成人av| 中文字幕观看av| 日韩1区2区日韩1区2区| 亚洲精品视频免费看| 精品成a人在线观看| 国产精品影片在线观看| 精品久久一二三| 大地资源二中文在线影视观看 | 四虎一区二区| 中文字幕一区二区三区人妻在线视频 | 日韩电影网1区2区| 亚洲国产高清aⅴ视频| 亚洲国产日韩欧美在线图片| 国产精品久久久久久搜索| 国产精品久久久久久久免费大片| 97在线国产视频| 好看的av在线| 国产欧美日产一区| 欧美一级高清片| 欧美日韩国产一二| 久久久午夜影院| 国产精品久久久久久久久搜平片| 97高清免费视频| 亚洲午夜久久久久久久久| 看片的网站亚洲| 伊人久久免费视频| 男女午夜激情视频| 精品人妻一区二区三区日产乱码| 欧美日韩视频在线第一区| 国产精品久久久久久久天堂第1集| www.久久91| jizz国产视频| 欧美又粗又大又爽| 国产a∨精品一区二区三区不卡| 蜜臀av午夜一区二区三区| 久久在线免费观看| 婷婷丁香激情综合| 国产精品wwwwww| 午夜视频你懂的| 美女精品在线 | 日韩在线视频免费播放| 性做久久久久久免费观看欧美| 成人亚洲激情网| 内射毛片内射国产夫妻| 99精品国产热久久91蜜凸| 久久成人这里只有精品| 国产精品一区二区免费在线观看| 中文字幕手机在线观看| 97久久超碰精品国产| 亚洲精品videossex少妇| 正在播放91九色| 黄色av网站免费观看| 中文字幕不卡在线观看| 欧美精品在线播放| www.激情小说.com| 国产精品高潮呻吟av| 中文字幕日韩一区| 欧美日韩国产va另类| 欧美久久在线观看| av片免费观看| 色综合久久久久| 亚洲精品久久久久久一区二区| 亚洲在线精品视频| 欧美一区二区精美| 亚洲成人精品电影在线观看| av女人的天堂| 国产高清精品久久久久| 亚洲男人天堂久| 亚洲 欧美 日韩 国产综合 在线| 国产欧美日韩成人| 亚洲黄色免费电影| 欧美亚洲日本网站| 国产精品99精品无码视亚| 久久66热re国产|