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

CppExplore

一切像霧像雨又像風

  C++博客 :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
  29 隨筆 :: 0 文章 :: 280 評論 :: 0 Trackbacks

作者:CppExplore 網(wǎng)址:http://m.shnenglu.com/CppExplore/
一、 基礎(chǔ)知識
1、時間類型。
Linux下常用的時間類型有4個:time_t,struct timeval,struct timespec,struct tm。
(1)time_t是一個長整型,一般用來表示用1970年以來的秒數(shù)。
(2)Struct timeval有兩個成員,一個是秒,一個是微妙。

struct timeval {
               
long tv_sec;        /* seconds */
               
long tv_usec;  /* microseconds */
       }
;

(3)struct timespec有兩個成員,一個是秒,一個是納秒。

struct timespec{
                      time_t  tv_sec;         
/* seconds */
                      
long    tv_nsec;        /* nanoseconds */
              }
;

(4)struct tm是直觀意義上的時間表示方法:

struct tm {
                      
int     tm_sec;         /* seconds */
                      
int     tm_min;         /* minutes */
                      
int     tm_hour;        /* hours */
                      
int     tm_mday;        /* day of the month */
                      
int     tm_mon;         /* month */
                      
int     tm_year;        /* year */
                      
int     tm_wday;        /* day of the week */
                      
int     tm_yday;        /* day in the year */
                      
int     tm_isdst;       /* daylight saving time */
              }
;

2、 時間操作
(1) 時間格式間的轉(zhuǎn)換函數(shù)
主要是 time_t、struct tm、時間的字符串格式之間的轉(zhuǎn)換。看下面的函數(shù)參數(shù)類型以及返回值類型:

char *asctime(const struct tm *tm);
char *ctime(const time_t *timep);
struct tm 
*gmtime(const time_t *timep);
struct tm 
*localtime(const time_t *timep);
time_t mktime(struct tm 
*tm);

gmtime和localtime的參數(shù)以及返回值類型相同,區(qū)別是前者返回的格林威治標準時間,后者是當?shù)貢r間。
(2) 獲取時間函數(shù)
兩個函數(shù),獲取的時間類型看原型就知道了:

time_t time(time_t *t);
int gettimeofday(struct timeval *tv, struct timezone *tz);

前者獲取time_t類型,后者獲取struct timeval類型,因為類型的緣故,前者只能精確到秒,后者可以精確到微秒。
二、 延遲函數(shù)
主要的延遲函數(shù)有:sleep(),usleep(),nanosleep(),select(),pselect().

unsigned int sleep(unsigned int seconds);
void usleep(unsigned long usec);
int nanosleep(const struct timespec *req, struct timespec *rem);
int select(int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,struct timeval *timeout);
int pselect(int   n,   fd_set   *readfds,  fd_set  *writefds,  fd_set *exceptfds, const struct timespec *timeout, const sigset_t *sigmask);

alarm函數(shù)是信號方式的延遲,這種方式不直觀,這里不說了。
僅通過函數(shù)原型中時間參數(shù)類型,可以猜測sleep可以精確到秒級,usleep/select可以精確到微妙級,nanosleep和pselect可以精確到納秒級。
而實際實現(xiàn)中,linux上的nanosleep和alarm相同,都是基于內(nèi)核時鐘機制實現(xiàn),受linux內(nèi)核時鐘實現(xiàn)的影響,并不能達到納秒級的精度,man nanosleep也可以看到這個說明,man里給出的精度是:Linux/i386上是10 ms ,Linux/Alpha上是1ms。
這里有一篇文章http://blog.csdn.net/zhoujunyi/archive/2007/03/30/1546330.aspx,測試了不同延遲函數(shù)之間的精確度。文章給出的結(jié)論是linux上精度最高的是select,10ms級別。我在本機器測試select和pselect相當,都達到了1ms級的精度,精度高于文章中給出的10ms,sleep在秒級以上和usleep/nanosleep相當。下面貼下我機器上1ms時候的測試結(jié)果,其他不貼了:

sleep           1000          0      -1000 
usleep           
1000       2974       1974 
nanosleep        
1000       2990       1990 
select           
1000        991         -9 
pselect           
1000        990        -10 
gettimeofday           
1000       1000          0

而使用gettimeofday循環(huán)不停檢測時間,可精確微秒級,不過不適宜用來做定時器模塊。
因此后面的定時期模塊將選擇select為延遲函數(shù)。
三、 定時器模塊需求以及實現(xiàn)概述
1、需求。從實現(xiàn)結(jié)果的角度說來,需求就是最終的使用方式。呵呵,不詳細描述需求了,先直接給出我實現(xiàn)的CTimer類的三個主要接口:

Class CTimer{
Public:
CTimer(unsigned 
int vinterval,void (*vfunc)(CTimer *,void *),void *vdata,TimerType vtype);
void start();
void stop();
void reset(unsigned int vinterval);
}
;

使用定時器模塊的步驟如下:
(1) 實例化一個CTimer,參數(shù)的含義依次是:vinterval間隔時間(單位ms),vfunc是時間到回調(diào)的函數(shù),vdata回調(diào)函數(shù)使用的參數(shù),vtype定時器的類型,分一次型和循環(huán)型兩種。
(2) 調(diào)用start方法。
(3) 必要的時候調(diào)用stop和reset。
2、實現(xiàn)。簡單描述下定時器模塊的實現(xiàn),有一個manager單例類保存所有CTimer對象,開啟一線程運行延遲函數(shù),每次延遲間隔到,掃描保存CTimer的容器,對每個CTimer對象執(zhí)行減少時間操作,減少到0則執(zhí)行回調(diào)函數(shù)。對一次性CTimer,超時則從容器中刪除,循環(huán)型的將間隔時間重置,不從容器中移除。
CTimer的start執(zhí)行將對象插入到manager容器中操作;stop執(zhí)行將對象從manager容器中刪除的操作;reset執(zhí)行先刪除,重置間隔,然后再放到容器中,reset不改變CTimer的定時器類型屬性。
四、 定時器模塊的數(shù)據(jù)結(jié)構(gòu)選擇
Manager類的容器要頻繁進行的操作涉及插入、刪除、查詢等。
誤區(qū):(1)簡單看,好象該容器要是有序的,方便插入刪除等,貌似紅黑樹比較合適。其實不然,插入刪除操作的頻率很低,最頻繁的還是每次時延到,對容器的掃描并做時間減少操作,紅黑樹在做順序掃描相對鏈表并沒什么優(yōu)勢。
(2) 插入的時候依照順序鏈表的方式插入到合適的位置保持排序,以保證超時的對象都在鏈表的頭端。其實這也是沒必要的,每次時延到,對每一個對象都要做時間減少操作,因此不管是有序還是無序,都是一次掃描就執(zhí)行完下面操作:減少時間、判斷是否超時,是則執(zhí)行回調(diào),繼續(xù)判斷是什么類型,一次型的則執(zhí)行完就移除,循環(huán)型則執(zhí)行完直接重置間隔就可。
因此,只需要能快速插入頭、刪除結(jié)點、遍歷就好。我的實現(xiàn)直接使用BSD內(nèi)核中的數(shù)據(jù)結(jié)構(gòu)LIST,插入頭、刪除時間復雜度都是1,遍歷就不說了。linux下/usr/include/sys下有頭文件queue.h里也有LIST結(jié)構(gòu)以及操作的定義。貌似linux下的少了遍歷宏:

#define LIST_FOREACH(var, head, field)     \
 
for((var) = LIST_FIRST(head);     \
     (var)
!= LIST_END(head);     \
     (var) 
= LIST_NEXT(var, field))

五、 詳細實現(xiàn)
這里帖出主要的代碼,請重點關(guān)注CTimerManager:: process方法,不再詳細說了。需要詳細的全部代碼,可來信索取,整體代碼很簡單,就兩個類。

class CTimer
{
friend 
class CTimerManager;
public:
    typedef 
enum
    
{
        TIMER_IDLE
=0,  //start前以及手動調(diào)用stop后的狀態(tài)
        TIMER_ALIVE,  //在manager的list里時候的狀態(tài)
        TIMER_TIMEOUT  //超時后被移除的狀態(tài),循環(huán)型的沒有
    }
TimerState;
    typedef 
enum
    
{
        TIMER_ONCE
=0,  //一次型
        TIMER_CIRCLE   //循環(huán)型
    }
TimerType;
    CTimer(unsigned 
int vinterval,void (*vfunc)(CTimer *,void *),void *vdata,TimerType vtype);
    
void start();
    
void stop();
    
void reset(unsigned int vinterval);
    
~CTimer();
private:
    unsigned 
int id_;     //測試用
    unsigned int m_interval;  //間隔,不變
    unsigned int m_counter;  //開始設(shè)置為interval,隨延遲時間到,減少
    TimerState m_state;      //狀態(tài)
    TimerType m_type;        //類型
    void (*m_func)(CTimer *,void *);//回調(diào)函數(shù)
    void * m_data;  //回調(diào)函數(shù)參數(shù)
    LIST_ENTRY(CTimer) entry_;  //LIST的使用方式
}
;
/*構(gòu)造函數(shù)*/
CTimer::CTimer(unsigned 
int vinterval,void (*vfunc)(CTimer *,void *),void *vdata,TimerType vtype):

    m_interval(vinterval),m_counter(vinterval),
    m_state(TIMER_IDLE),m_type(vtype),
    m_func(vfunc),m_data(vdata)
{}
/*開始定時器*/
void CTimer::start()
{
    CTimerManager::instance()
->add_timer(this);
}

/*停止定時器*/
void CTimer::stop()
{
    CTimerManager::instance()
->remove_timer(this);
}

/*reset定時器*/
void CTimer::reset(unsigned int vinterval)
{
    CTimerManager::instance()
->remove_timer(this);
    m_counter
=m_interval=vinterval;
    CTimerManager::instance()
->add_timer(this);
}

/*析構(gòu)函數(shù),stop操作不能省略,避免delete前忘記stop*/
CTimer::
~CTimer()
{
    
if(m_state==TIMER_ALIVE)
        stop();
}

CTimerManager的:

class CTimerManager
{
public:
    
    typedef 
enum
    
{
        TIMER_MANAGER_STOP
=0,
        TIMER_MANAGER_START
    }
TimerManagerState;
    
    
static CTimerManager * instance();
    
void add_timer(CTimer * vtimer);//線程安全的add
    void remove_timer(CTimer * vtimer);//線程安全的remove
    void start();  //開始process線程
    void stop();  //停止process線程
    void dump();
protected:
    
static void * process(void *); //實際的定時器時間延遲線程
private:    
    
void add_timer_(CTimer * vtimer);//非線程安全的add
    void remove_timer_(CTimer * vtimer);//非線程安全的remove
    
    CTimerManager();
    
static pthread_mutex_t m_mutex;
    
static CTimerManager * m_instance;
    
    TimerManagerState m_state;
    LIST_HEAD(,CTimer) list_;  
//LIST使用方式

    
static unsigned int mark;  //測試,配合dump
}
;
/*singlton的double-check實現(xiàn)*/
CTimerManager 
* CTimerManager::instance()
{
    
if(m_instance==NULL)
    
{
        pthread_mutex_lock(
&m_mutex);
        
if(m_instance==NULL)
        
{
            m_instance
=new CTimerManager();
        }

        pthread_mutex_unlock(
&m_mutex);
    }

    
return m_instance;
}

/*process必須static,不能操作非static屬性,因此傳遞this指針*/
void CTimerManager:: start()
{
         if(m_state==TIMER_MANAGER_STOP){
    m_state
=TIMER_MANAGER_START;
    pthread_t pid;
    pthread_create(
&pid,0,process,this);
      }
}

/*定時器模塊延遲時間線程*/
void * CTimerManager:: process(void * arg)
{
    pthread_detach(pthread_self());

    CTimerManager 
*manage=(CTimerManager *)arg;

    CTimer 
*item;
    struct timeval start,end;
    unsigned 
int delay;
    
    struct timeval tm;
    gettimeofday(
&end,0);
/*使用狀態(tài)控制線程運行,進而容易實現(xiàn)stop,也可以使用pthread_cancel粗暴的停止,需要考慮暫停點等問題*/
    
while(manage->m_state==TIMER_MANAGER_START)
    
{
        tm.tv_sec
=0;
        tm.tv_usec
=DEFULT_INTERVAL*1000;
        start.tv_sec
=end.tv_sec;
        start.tv_usec
=end.tv_usec;
/*不同系統(tǒng)的延遲函數(shù)精度不同,如果需要替換為其他延遲函數(shù),這附近修改下就好*/
        
while(select(0,0,0,0,&tm)<0&&errno==EINTR);
        gettimeofday(
&end,0);

        delay
=(end.tv_sec-start.tv_sec)*1000+(end.tv_usec-start.tv_usec)/1000;
        pthread_mutex_lock(
&manage->m_mutex);

        LIST_FOREACH(item, 
&(manage->list_), entry_)
        
{
            item
->m_counter<delay?item->m_counter=0:item->m_counter-=delay;
            
if(item->m_counter==0)
            
{
                
if(item->m_func)
                item
->m_func(item,item->m_data);

                
if(item->m_type==CTimer::TIMER_ONCE)
                
{
/*一次型的,超時,移除,并狀態(tài)CTimer::TIMER_TIMEOUT*/
                    manage
->remove_timer_(item);
                    item
->m_state=CTimer::TIMER_TIMEOUT;
                }

                
else if(item->m_type==CTimer::TIMER_CIRCLE)
                
{
/*循環(huán)型的,重置counter就好*/
                    item
->m_counter=item->m_interval;
                }

            }

        }


        pthread_mutex_unlock(
&manage->m_mutex);
    }

}



六、 討論
(1)精度問題。精度高,實時性高,但要求select等待的時間縮短,進而增加對LIST結(jié)構(gòu)的掃描操作。精度低,實時性差,但會增加定時器線程的睡眠時間,減少對cpu的占用。一般的應(yīng)用系統(tǒng),應(yīng)該盡量降低精度,避免不必要的掃描,對具體系統(tǒng)可考察所用到的所有定時器的實際間隔,在允許的情況下,盡量降低精度,可通過修改代碼中的宏實現(xiàn)。為了降低定時器線程對cpu的占有時間,甚有更為粗獷型的定時器模塊實現(xiàn)為將延遲時間取list中最小的那個間隔,保證每次延遲時間到都有回調(diào)。
(2)加鎖區(qū)域問題。本文中的定時器模塊實現(xiàn),將定時器對象的時間減少以及函數(shù)回調(diào)的執(zhí)行等再同一個臨界區(qū)內(nèi)執(zhí)行,而有的定時器模塊實現(xiàn)是在加鎖區(qū)域執(zhí)行“時間減少”操作,將減少到0的對象放到另一個超時鏈表中,解鎖后再單獨掃描超時鏈表執(zhí)行回調(diào)操作。很明顯,后者縮短了加鎖時間,能及時響應(yīng)其他的線程的定時器對象的start以及stop操作。但是后者對定時器操作的時序性有誤差,直觀反應(yīng)就是可能在定時器執(zhí)行了stop操作以后,仍然會有超時回調(diào)發(fā)生,特別是回調(diào)參數(shù)是指針的情況,可能引起難以發(fā)現(xiàn)的bug,增加調(diào)試困難。在衡量兩者的利弊后,本文采用延長加鎖時間以保證操作的時序性。因此,在實際的使用,回調(diào)函數(shù)應(yīng)盡快返回,另一方面,盡量減少系統(tǒng)內(nèi)使用的定時器數(shù)目,這個主要原因是延遲時間到要掃描LIST,哪種方式都避免不了。

七、使用示例

#include "timer_manager.h"
#include 
<stdio.h>
#include 
<unistd.h>
#include 
<stdlib.h>
void func(CTimer * timer, void *data)
{
    printf(
"hi,%d\n",(int
)(data));
}

/*隨便寫的,湊合著看吧。沒有CTimerManager::instance()->stop();也沒new對象。定時器對象可多次start和stop,使用上對暴露的接口沒有任何的契約式限制,可隨意調(diào)用*/
int main()
{
    CTimerManager::instance()
->
start();
    CTimer a(
1000,func,(void *)1
,CTimer::TIMER_CIRCLE);
    CTimer a1(
2000,func,(void *)11
,CTimer::TIMER_ONCE);
    CTimer a2(
3000,func,(void *)12
,CTimer::TIMER_ONCE);
    CTimer a3(
1000,func,(void *)13
,CTimer::TIMER_ONCE);
    
    a.start();
    a1.start();
    a2.start();
    a3.start();
    a.start();
    a1.start();
    a2.start();
    a3.start();

    sleep(
1
);
    CTimerManager::instance()
->
dump();
    sleep(
1
);
    CTimerManager::instance()
->
dump();
    a.reset(
2000
);
    a1.stop();
    a3.stop();

    sleep(
10
);
    
return 0
;
}

八、后記
昨晚寫好文章,不知為何無故丟失大半,郁悶。今早醒來,感覺還是有點地方要修改,:在start定時器線程的時候,傳入精度和誤差補償,一是根據(jù)實際需要調(diào)整精確度,二是彌補延遲函數(shù)的稍許誤差,以具有更好的伸縮性和精確度。本文旨在說明定時器模塊的內(nèi)部實現(xiàn)機制,詳細細節(jié)不再修改了。
posted on 2008-04-02 23:19 cppexplore 閱讀(13067) 評論(31)  編輯 收藏 引用

評論

# re: 【原創(chuàng)】系統(tǒng)設(shè)計之 定時器 2008-04-02 23:33 Colin
精度是個問題啊。。  回復  更多評論
  

# re: 【原創(chuàng)】系統(tǒng)設(shè)計之 定時器 2008-04-02 23:49 cppexplore
@Colin
你可真快啊,我有個習慣:把寫的丟失,中途會提交,然后再修改再提交直到結(jié)束。最后寫完,就已經(jīng)有回復了,呵呵。
精度問題,只能在系統(tǒng)能力之內(nèi)盡量了,一般的應(yīng)用server非實時性很強的系統(tǒng)需要不了微秒級的精度,我的實際應(yīng)用秒級夠了。
  回復  更多評論
  

# re: 【原創(chuàng)】系統(tǒng)設(shè)計之 定時器 2008-04-03 00:04 Colin
@cppexplore
睡覺前看了一下。

以前在bsd下做過一個性能測試程序,就為精度問題頭痛了很久。。
  回復  更多評論
  

# re: 【原創(chuàng)】系統(tǒng)設(shè)計之 定時器 2008-04-03 00:08 cppexplore
@Colin
呵呵,你的精度要求太高了。零點了,該睡了。8888  回復  更多評論
  

# re: 【原創(chuàng)】系統(tǒng)設(shè)計之 定時器[未登錄] 2008-04-03 14:07 創(chuàng)
收藏.
  回復  更多評論
  

# re: 【原創(chuàng)】系統(tǒng)設(shè)計之 定時器 2008-04-03 16:40 kw
每次都循環(huán)整個鏈表,效率似乎不高吧。   回復  更多評論
  

# re: 【原創(chuàng)】系統(tǒng)設(shè)計之 定時器 2008-04-03 16:45 cppexplore
@kw
呵呵,想了下,真是不高啊。
直接保存gettimeoftime()+interval的時間做間隔,并在LIST中排序應(yīng)該是最好的方法。  回復  更多評論
  

# re: 【原創(chuàng)】系統(tǒng)設(shè)計之 定時器 2008-04-03 16:55 eXile
不知老兄有沒有研究過boost::asio的定時器定現(xiàn), 好象用的也是select  回復  更多評論
  

# re: 【原創(chuàng)】系統(tǒng)設(shè)計之 定時器(一)[未登錄] 2008-04-03 21:59 cppexplore
@eXile
第三方庫中的定時器實現(xiàn)還沒看呢,以后有時間整理下。最近是不準備研究了。  回復  更多評論
  

# re: 【原創(chuàng)】技術(shù)系列之 定時器(一) 2008-11-25 13:40 卡通服裝
要求都好高  回復  更多評論
  

# re: 【原創(chuàng)】技術(shù)系列之 定時器(一) 2008-11-27 18:50 Song
Hi, 可以發(fā)一份源碼給我嗎?

leezjs[at]gmail.com

謝謝  回復  更多評論
  

# re: 【原創(chuàng)】技術(shù)系列之 定時器(一) 2009-04-15 13:11 包裝機
這個要求不算高吧  回復  更多評論
  

# re: 【原創(chuàng)】技術(shù)系列之 定時器(一) 2009-07-27 12:59 套袋收縮機
路過,走走  回復  更多評論
  

# re: 【原創(chuàng)】技術(shù)系列之 定時器(一) 2009-08-04 21:21 farman
看完很有收獲,寫的非常好,贊一個!
提點意見,建議定時器隊列不要用動態(tài)內(nèi)存的鏈表,最好限制一下系統(tǒng)中最大定時器個數(shù)。  回復  更多評論
  

# re: 【原創(chuàng)】技術(shù)系列之 定時器(一) 2009-08-26 11:46 四海游魚
可以發(fā)一份兒給我嗎?
我的郵箱是 zshuming@yahoo.cn  回復  更多評論
  

# re: 【原創(chuàng)】技術(shù)系列之 定時器(一) 2009-08-31 17:44 shiqyn
不錯,支持樓主。  回復  更多評論
  

# re: 【原創(chuàng)】技術(shù)系列之 定時器(一) 2009-12-27 16:31 難得糊涂
好像已經(jīng)過了一年了,請問還能發(fā)一份么,謝謝
usetowork@163.com  回復  更多評論
  

# re: 【原創(chuàng)】技術(shù)系列之 定時器(一) 2010-07-20 14:04 Plocklsh
又過了半年了,還能把源碼發(fā)一份給我嘛,謝謝了,416573704@qq.com  回復  更多評論
  

# re: 【原創(chuàng)】技術(shù)系列之 定時器(一)[未登錄] 2010-08-30 10:21 by
是的,排序LIST之后,只要進行一次判斷就行了,就不用循環(huán)判斷了。  回復  更多評論
  

# re: 【原創(chuàng)】技術(shù)系列之 定時器(一) 2012-03-08 13:30 aiolia
guyaping1234@163.com,還可以發(fā)一份源碼嗎??  回復  更多評論
  

# re: 【原創(chuàng)】技術(shù)系列之 定時器(一) 2012-07-12 15:51 maimai
maimai2009@126.com
還可以發(fā)一份源碼嗎??
謝謝了!  回復  更多評論
  

# re: 【原創(chuàng)】技術(shù)系列之 定時器(一)[未登錄] 2012-07-26 16:43 rpg_kiss
您好!rpg_kill@foxmail.com
能發(fā)一份源代碼嗎,謝謝!  回復  更多評論
  

# re: 【原創(chuàng)】技術(shù)系列之 定時器(一) 2012-12-09 20:33 ZeroClock
你的代碼寫得很漂亮。
能發(fā)份原碼給我欣賞學習下嗎?
353230424@qq.com
謝謝  回復  更多評論
  

# re: 【原創(chuàng)】技術(shù)系列之 定時器(一) 2012-12-12 11:06 lala
能給我發(fā)一份源代碼
laba1022@yahoo.com.cn
謝謝  回復  更多評論
  

# re: 【原創(chuàng)】技術(shù)系列之 定時器(一)[未登錄] 2012-12-13 12:00 gary
lb2421428@126.com 望能提供代碼研究  回復  更多評論
  

# re: 【原創(chuàng)】技術(shù)系列之 定時器(一) 2012-12-21 14:48 arbin
arbin00@gmail.com 謝謝  回復  更多評論
  

# re: 【原創(chuàng)】技術(shù)系列之 定時器(一) 2012-12-23 09:38 cppexplore
當年寫的這么一個垃圾實現(xiàn), 大家就不要再繼續(xù)留言了 呵呵  回復  更多評論
  

# re: 【原創(chuàng)】技術(shù)系列之 定時器(一) 2013-07-03 17:37 詎訌
三年了啊。三年了。哈哈  回復  更多評論
  

# re: 【原創(chuàng)】技術(shù)系列之 定時器(一) 2014-10-21 17:26 rqf
給我一個啊,r187@foxmail.com  回復  更多評論
  

# re: 【原創(chuàng)】技術(shù)系列之 定時器(一) 2014-10-21 17:30 rqf
謝謝拉  回復  更多評論
  

# re: 【原創(chuàng)】技術(shù)系列之 定時器(一)[未登錄] 2014-10-23 14:37 cppexplore
@rqf
說實話,本文本質(zhì)很垃圾  回復  更多評論
  


只有注冊用戶登錄后才能發(fā)表評論。
網(wǎng)站導航: 博客園   IT新聞   BlogJava   博問   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精品热6080yy久久| 亚洲日本在线观看| 亚洲激情一区二区三区| 亚洲精品之草原avav久久| 亚洲级视频在线观看免费1级| 欧美激情精品久久久久久变态| 欧美成人一品| 99国产麻豆精品| 亚洲欧美国产77777| 欧美一级欧美一级在线播放| 久久久综合网站| 欧美日本韩国一区| 国产欧美一区二区精品忘忧草| 国语自产精品视频在线看8查询8| 久久国产婷婷国产香蕉| 国产欧美一区二区精品性色| 国产精品影片在线观看| 国产视频在线观看一区| 亚洲国产mv| 亚洲午夜精品| 久久黄色小说| 欧美激情精品久久久久久蜜臀| 亚洲精品欧洲| 亚洲视频国产视频| 久久久亚洲精品一区二区三区| 欧美xart系列高清| 国产欧美精品一区二区色综合| 一区在线观看视频| 国产精品99久久久久久久vr | 久久精品亚洲一区| 欧美精品99| 国产午夜精品久久久久久免费视 | 亚洲精品孕妇| 午夜伦理片一区| 欧美高清你懂得| 亚洲欧美三级在线| 欧美成人一区二区三区| 国产欧美精品一区aⅴ影院| 亚洲美女在线观看| 毛片一区二区| 亚洲欧美日韩国产精品 | 欧美精品三级日韩久久| 狠狠色狠狠色综合人人| 亚洲性夜色噜噜噜7777| 亚洲精品乱码久久久久久蜜桃麻豆| 亚洲一区综合| 亚洲国产精品一区二区第四页av| 亚洲一区二区久久| 欧美激情视频一区二区三区在线播放| 国产视频久久久久久久| 亚洲视频一起| 亚洲国产精品尤物yw在线观看| 亚洲欧美日韩在线| 欧美一区精品| 国产美女一区二区| 99精品国产在热久久| 国产精品系列在线| 亚洲欧美成人一区二区在线电影| 亚洲日韩欧美视频| 欧美大片91| 91久久国产自产拍夜夜嗨| 久久亚洲视频| 久久久xxx| 亚洲电影天堂av| 欧美不卡视频一区| 亚洲一区二区三区激情| 欧美一区二区在线免费播放| 一区二区三区日韩精品视频| 欧美精品一区二区视频| 最新国产乱人伦偷精品免费网站 | 欧美大片免费观看| 麻豆精品精华液| 亚洲欧洲日产国产综合网| 欧美大片专区| 欧美日韩精品不卡| 亚洲一区二区三区精品在线观看| 99re热精品| 国产精品美女一区二区| 欧美一区二区三区四区在线观看地址| 亚洲欧美激情在线视频| 国产夜色精品一区二区av| 久久九九99| 久久亚洲影音av资源网| 日韩视频一区| 亚洲午夜精品17c| 国产一区二区高清视频| 乱码第一页成人| 欧美激情四色 | 日韩视频一区二区三区在线播放| 欧美日韩18| 欧美一级视频精品观看| 久久精品夜色噜噜亚洲aⅴ| 亚洲成人在线网站| 99v久久综合狠狠综合久久| 国产欧美短视频| 欧美成人高清| 欧美午夜免费电影| 久久久噜噜噜| 欧美国产视频在线| 久久国产精品一区二区三区| 女仆av观看一区| 欧美中文字幕不卡| 久久国产66| 亚洲视频中文| 久久亚洲风情| 欧美一区二区高清在线观看| 欧美成人一品| 免播放器亚洲一区| 国产精品久久久久久久久久免费| 久久久www成人免费毛片麻豆| 欧美紧缚bdsm在线视频| 久久免费99精品久久久久久| 欧美日韩精品一本二本三本| 久久夜色精品| 国产欧美精品一区aⅴ影院| 亚洲精品久久嫩草网站秘色| 亚洲高清一区二| 久久久久国产免费免费| 久久激情中文| 国产欧美日韩| 亚洲一区二区免费看| 国产精品99久久99久久久二8| 免费一级欧美在线大片| 久久综合伊人77777麻豆| 国产视频精品xxxx| 性欧美大战久久久久久久久| 欧美亚洲免费电影| 欧美午夜不卡| 宅男噜噜噜66一区二区66| 亚洲精品护士| 开心色5月久久精品| 久久中文字幕一区| 国产色产综合产在线视频| 午夜精品久久久久久久久| 亚洲欧美日韩一区二区在线| 欧美日韩卡一卡二| 亚洲日本激情| 最新亚洲视频| 欧美另类99xxxxx| 999在线观看精品免费不卡网站| 国模大胆一区二区三区| 午夜精品久久久久久久99水蜜桃| 久久爱91午夜羞羞| 欧美一区成人| 国产美女一区二区| 久久精品在线播放| 欧美福利专区| 乱人伦精品视频在线观看| 欧美日本不卡高清| 夜夜精品视频| 夜夜嗨av一区二区三区四区| 久久婷婷麻豆| 久久都是精品| 国产日韩欧美精品| 久久国产精品久久w女人spa| 欧美中文字幕视频| 国产精品视频一区二区高潮| 久久精品国产第一区二区三区| 国产一区久久久| 欧美激情区在线播放| 亚洲精选一区二区| 亚洲日本理论电影| 欧美ed2k| 99国产精品国产精品久久| 欧美a级一区| 亚洲精品欧洲| 亚洲一区二区视频在线观看| 国产日韩欧美在线| 久久国产精品毛片| 免费亚洲一区二区| 亚洲精品在线观看免费| 国产精品男女猛烈高潮激情 | 欧美日韩天天操| 久久成人免费日本黄色| 亚洲国产日韩一区二区| 欧美成人精品在线视频| 亚洲国产精品激情在线观看| 亚洲日本成人| 欧美国产丝袜视频| 夜夜嗨av一区二区三区免费区| 99在线热播精品免费| 国产精品高潮久久| 日韩亚洲欧美一区| 欧美成人精品| 久久精品一区二区三区中文字幕| 免费观看国产成人| 国产精品亚洲欧美| 小黄鸭精品密入口导航| 久久久久久久91| 一区二区三区www| 国产精品igao视频网网址不卡日韩 | 校园激情久久| 亚洲国产高清在线观看视频|