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

隨筆 - 6  文章 - 11  trackbacks - 0
<2011年2月>
303112345
6789101112
13141516171819
20212223242526
272812345
6789101112

常用鏈接

留言簿(1)

隨筆檔案

搜索

  •  

最新評(píng)論

閱讀排行榜

評(píng)論排行榜

      在C++中要進(jìn)行并發(fā)處理,不可避免要使用多線程,在傳統(tǒng)的教科書中,大家都是采用最原始的多線程技術(shù),應(yīng)用邏輯和線程并發(fā)策略緊密綁定。
      在一個(gè)典型的服務(wù)器程序中,客戶端的請(qǐng)求往往包含了很多不同的邏輯命令,如在一個(gè)線程處理函數(shù)中,需要根據(jù)客戶端的命令代碼處理不同的業(yè)務(wù)邏輯:

int thrad_main(int cmd_id,char *data){
   switch(cmd_id)
   {
   case 1:
      ...
      break;
   case 2:
      ...
      break;
   }
}

   如此這般,業(yè)務(wù)處理邏輯和線程邏輯緊密耦合,這是一種很“丑陋”的代碼。
   如何通過一種優(yōu)雅的方法,分離并發(fā)邏輯和業(yè)務(wù)邏輯,通過通用的并發(fā)框架,業(yè)務(wù)邏輯設(shè)計(jì)者只需要關(guān)心自己的邏輯代碼,交給“線程池”去處理即可,而不需要去關(guān)心如何創(chuàng)建線程,等待線程結(jié)果這些瑣碎的“小事”?

   很簡(jiǎn)單,高手出招,必談模式,下面是一種常用的并發(fā)模式,領(lǐng)導(dǎo)者/追隨者線程池模型:

   在一組預(yù)先分配的線程中通過“互斥”鎖來(lái)同步線程之間的行為,“線程”們通過“民主選舉”選出一位代表“領(lǐng)導(dǎo)者”站在最前端接收請(qǐng)求,拿到“任務(wù)”后,就從身后的候選“繼任者”中選出一個(gè)線程代替自己作為“領(lǐng)導(dǎo)者”,自己則變成“工作者”就跑到后面默默去執(zhí)行處理命令,這個(gè)“任務(wù)”是一個(gè)包含待處理數(shù)據(jù)和處理邏輯的自說(shuō)明性任務(wù),也就是說(shuō)所有的線程不必事先知道怎么處理接收到的任務(wù),因?yàn)樗玫降?#8220;任務(wù)包”中就包含了如何處理任務(wù)的說(shuō)明。就像一個(gè)“代工工廠”的工人一樣,無(wú)需任何文化基礎(chǔ),會(huì)干活就行。
   那如何實(shí)現(xiàn)自說(shuō)明任務(wù)呢?我們定義了一種稱為“Method_Request”的對(duì)象,它包含一個(gè)接口“virtual int call (void) = 0;”,線程池接受的任務(wù)就是這種Method_Request對(duì)象的實(shí)例,比如一個(gè)通知線程池結(jié)束工作的Method_Request可以定義為如下的類:
1     class ExitRequest : public ACE_Method_Request
2     {
3     public:
4         virtual int call (void){
5             return -1;  // Cause exit.
6         }
7     };
8 
      我們重載call接口,添加處理這個(gè)請(qǐng)求的邏輯代碼,由于僅僅實(shí)現(xiàn)通知線程池結(jié)束工作的操作,我們返回一個(gè)特殊值“-1”,即可只是線城池:“工作完成了,你趕快洗洗睡吧!”,線程池會(huì)檢查Method_Request對(duì)象的返回值,如果是“0”就是處理正常完成,繼續(xù)等待下一個(gè)任務(wù),如果是“-1”,就關(guān)閉所有線程。

      再來(lái)一個(gè)復(fù)雜點(diǎn)的例子,派生的Method_Request不僅有處理邏輯,還包括了需要處理的數(shù)據(jù):
 1 
 2 class M2M_EventRequest : public ACE_Method_Request
 3 {
 4     // Lua解釋器,每個(gè)事件使用自己?jiǎn)为?dú)的腳本上下文
 5     LuaVM::ALEE_LuaService & m_svcs;
 6     ALEE_ScriptList_t & m_cmds;
 7 
 8     // 事件內(nèi)容
 9     std::string m_type_name;
10     xml_event_t m_xml_event;
11 
12     // 調(diào)試信息
13     DebugInfo_ptr m_debug;
14 
15 public:
16     M2M_EventRequest(
17         LuaVM::ALEE_LuaService & svcs,
18         ALEE_ScriptList_t &cmds,
19         string const & type_name,
20         xml_event_t event);
21 
22     M2M_EventRequest(
23         LuaVM::ALEE_LuaService & svcs,
24         ALEE_ScriptList_t &cmds,
25         string const & type_name,
26         xml_event_t event,
27         DebugInfo_ptr debug);
28 
29     virtual ~M2M_EventRequest (void);
30 
31     virtual int call (void);
32 };
33 
      這個(gè)Method_Request的功能是,命令線程池調(diào)用Lua解析器處理一段腳本代碼,詳細(xì)邏輯就不解釋了,僅僅是一個(gè)示例,我們的重點(diǎn)在于線程池的實(shí)現(xiàn)。
      下面就公布這個(gè)“萬(wàn)能線程池的”實(shí)現(xiàn),其實(shí)這是一個(gè)基于ACE的線程庫(kù)實(shí)現(xiàn)的“領(lǐng)導(dǎo)者/追隨者”模式,我在其基礎(chǔ)上進(jìn)行了改進(jìn),增加了自適應(yīng)功能,可以根據(jù)請(qǐng)求隊(duì)列的負(fù)載,自動(dòng)調(diào)整線程池中的線程數(shù)目。
      閑話少說(shuō),上代碼,看得懂的童鞋恭喜你內(nèi)力深厚,還望多提寶貴意見,看不懂得小盆友也可以努力學(xué)習(xí),提高自己:
// LeaderFollower.h
 1 #pragma once
 2 
 3 #include "dllmain.h"
 4 #include <map>
 5 #include <ace/Synch.h>    // ACE_Thread_Mutex
 6 #include <ace/Task.h>    // ACE_Task
 7 
 8 // 線程狀態(tài)
 9 enum LF_Status_t
10 {
11     TH_LEADER_ACTIVE,
12     TH_FOLLOWER,
13     TH_WORKER,
14     TH_READY,
15     TH_STOP,
16 };
17 
18 struct LF_StatusTime_t
19 {
20     LF_Status_t    status;
21     ACE_Time_Value working_tv;
22     ACE_Time_Value start_time;
23     ACE_Time_Value stop_time;
24     ACE_Time_Value work_start;
25     ACE_Time_Value work_time;
26 };
27 
28 typedef std::map<ACE_thread_t,LF_StatusTime_t>  LF_StatusTimeList_t;
29 
30 class LF_Follower;
31 
32 // 領(lǐng)導(dǎo)者-追隨者線程池 模式實(shí)現(xiàn)
33 class CPPXCORBA_API LeaderFollower
34 {
35 public:
36     LeaderFollower(void);
37     ~LeaderFollower(void);
38 
39 protected:
40     LF_Follower * make_follower(void);
41     int     become_leader(void);
42     int     elect_new_leader(void);
43     bool leader_active(void);
44     void set_active_leader(ACE_thread_t leader);
45 
46 private:
47     ACE_Unbounded_Queue<LF_Follower*>   m_followers;
48     ACE_Thread_Mutex                    m_followers_lock;
49     ACE_Thread_Mutex                    m_leader_lock;
50     ACE_thread_t                        m_current_leader;
51 
52     //////////////////////////////////////////////////////////////////////////
53     /// 線程池狀態(tài)監(jiān)控
54 public:
55     const LF_StatusTimeList_t & get_status(voidconst;
56     const float get_load_rate(voidconst;
57 
58 protected:
59     void set_status(LF_Status_t status);
60     void set_worktime(ACE_Time_Value work_time);
61 
62 private:
63     LF_StatusTimeList_t m_status_time_list;
64     ACE_Thread_Mutex    m_status_lock;
65 };
66 

// LeaderFollower.cpp
  1 #include "stdafx.h"
  2 #include "LeaderFollower.h"
  3 #include "../cppx.core/dllmain.h"
  4 
  5 // 追隨者標(biāo)記
  6 class LF_Follower
  7 {
  8     ACE_Condition<ACE_Thread_Mutex> m_cond;
  9     ACE_thread_t                    m_owner;
 10 
 11 public:
 12     LF_Follower(ACE_Thread_Mutex &leader_lock) : m_cond(leader_lock) {
 13         m_owner = ACE_Thread::self();
 14     }
 15     int wait(void){
 16         return m_cond.wait();
 17     }
 18     int signal(void){
 19         return m_cond.signal();
 20     }
 21     ACE_thread_t owner(void){
 22         return m_owner;
 23     }
 24 
 25 };
 26 
 27 //////////////////////////////////////////////////////////////////////////
 28 LeaderFollower::LeaderFollower(void) :
 29 m_current_leader(0)
 30 {
 31 }
 32 
 33 LeaderFollower::~LeaderFollower(void)
 34 {
 35 }
 36 
 37 LF_Follower * 
 38 LeaderFollower::make_follower( void )
 39 {
 40     ACE_GUARD_RETURN(ACE_Thread_Mutex, follower_mon, m_followers_lock, 0);
 41     
 42     LF_Follower *fw;
 43     ACE_NEW_RETURN(fw, LF_Follower(m_leader_lock), 0);
 44     m_followers.enqueue_tail(fw);
 45     //ACE_DEBUG((LM_ERROR, ACE_TEXT("(%t) make_follower \t: Now has %d followers.\n"), m_followers.size()));
 46     return fw;
 47 }
 48 
 49 int 
 50 LeaderFollower::become_leader( void )
 51 {
 52     ACE_GUARD_RETURN(ACE_Thread_Mutex, leader_mon, m_leader_lock, -1);
 53 
 54     if( leader_active() && m_current_leader != ACE_Thread::self() ){
 55         while(leader_active()){
 56             set_status(TH_FOLLOWER);
 57             auto_ptr<LF_Follower> fw(make_follower());
 58             fw->wait();         // Wait until told to do so.
 59         }
 60     }
 61 
 62     // Mark yourself as the active leader.
 63     set_active_leader(ACE_Thread::self());
 64     set_status(TH_LEADER_ACTIVE);
 65     //ACE_DEBUG((LM_DEBUG, ACE_TEXT("(%t) become_leader \t: Becoming the leader.\n")));
 66     return 0;
 67 }
 68 
 69 int 
 70 LeaderFollower::elect_new_leader( void )
 71 {
 72     ACE_GUARD_RETURN(ACE_Thread_Mutex, leader_mon, m_leader_lock, -1);
 73 
 74     set_active_leader(0);
 75 
 76     // Wake up a follower
 77     if!m_followers.is_empty() ){
 78         ACE_GUARD_RETURN(ACE_Thread_Mutex, follower_mon, m_followers_lock, -1);
 79 
 80         // Get the old follower.
 81         LF_Follower *fw;
 82         if( m_followers.dequeue_head(fw) != 0 )
 83             return -1;
 84 
 85         //ACE_DEBUG((LM_ERROR, ACE_TEXT("(%t) elect_new_leader : Resigning and electing %d.\n"), fw->owner()));
 86         return (fw->signal() == 0? 0 : -1;
 87     }
 88 
 89     //ACE_DEBUG((LM_ERROR, ACE_TEXT("(%t) elect_new_leader : Oops no followers left\n")));
 90     return -1;
 91 }
 92 
 93 bool 
 94 LeaderFollower::leader_active( void )
 95 {
 96     return (m_current_leader != 0);
 97 }
 98 
 99 void 
100 LeaderFollower::set_active_leader( ACE_thread_t leader )
101 {
102     m_current_leader = leader;
103 }
104 
105 void LeaderFollower::set_worktime( ACE_Time_Value work_time )
106 {
107     ACE_GUARD(ACE_Thread_Mutex, status_guard, m_status_lock);
108     LF_StatusTime_t & info = m_status_time_list[ACE_Thread::self()];
109     info.working_tv = work_time;
110 }
111 
112 void LeaderFollower::set_status( LF_Status_t status )
113 {
114     ACE_GUARD(ACE_Thread_Mutex, status_guard, m_status_lock);
115     LF_StatusTime_t & info = m_status_time_list[ACE_Thread::self()];
116     switch(status)
117     {
118     case TH_READY:
119         info.start_time = ACE_OS::gettimeofday();
120         break;
121     case TH_STOP:
122         info.stop_time = ACE_OS::gettimeofday();
123         break;
124     case TH_WORKER:
125         info.work_start = ACE_OS::gettimeofday();
126         break;
127     case TH_LEADER_ACTIVE:
128     case TH_FOLLOWER:
129         if( info.status == TH_WORKER )
130             info.work_time += ACE_OS::gettimeofday() - info.work_start;
131         break;
132     }
133     info.status = status;
134 }
135 
136 const LF_StatusTimeList_t & 
137 LeaderFollower::get_status( void ) const
138 {
139     return m_status_time_list;
140 }
141 
142 const float 
143 LeaderFollower::get_load_rate( void ) const
144 {
145     ACE_Time_Value work_time,run_time;
146     foreach(const LF_StatusTimeList_t::value_type & info,get_status()){
147         if( info.second.status != TH_STOP ){
148             work_time += info.second.work_time;
149             run_time += ACE_OS::gettimeofday() - info.second.start_time;
150         }
151     }
152     return (float)work_time.usec()/run_time.usec()*100;
153 }
154 

// LF_ThreadPool.h
 1 #pragma once
 2 
 3 #include "LeaderFollower.h"
 4 
 5 #include <ace/Task.h>
 6 #include <ace/Activation_Queue.h>
 7 #include <ace/Method_Request.h>
 8 
 9 class CPPXCORBA_API LF_ThreadPool :
10     public ACE_Task_Base,
11     public LeaderFollower
12 {
13     class ExitRequest : public ACE_Method_Request
14     {
15     public:
16         virtual int call (void){
17             return -1;  // Cause exit.
18         }
19     };
20 
21     bool m_bShutdown;
22     bool m_bRunning;
23     ACE_Activation_Queue m_activation_queue_;
24 
25     static const size_t ScheduleTime = 10;
26     static const size_t MinThreadNum = 10;
27     static const size_t MaxThreadNum = 20;
28 
29 public:
30     LF_ThreadPool(void);
31     ~LF_ThreadPool(void);
32 
33     virtual int svc(void);
34 
35     int start_stread_pool( void );
36     int stop_thread_pool( void );
37     int post_request( ACE_Method_Request *request );
38 
39     int get_queue_load(void){ return m_activation_queue_.method_count(); }
40     int get_max_thread(void){ return MaxThreadNum; }
41     int get_min_thread(void){ return MinThreadNum; }
42 
43 private:
44     int _fork_new_thread( void );
45     int _post_exit_request(void);
46 };
47 

// LF_ThreadPool.cpp
  1 #include "stdafx.h"
  2 #include "LF_ThreadPool.h"
  3 
  4 LF_ThreadPool::LF_ThreadPool(void) :
  5 m_bShutdown(false),
  6 m_bRunning(false)
  7 {
  8 }
  9 
 10 LF_ThreadPool::~LF_ThreadPool(void)
 11 {
 12 }
 13 
 14 int LF_ThreadPool::svc( void )
 15 {
 16     //ACE_DEBUG((LM_ERROR, ACE_TEXT("(%t) Thread started.\t: %d working threads left.\n"),thr_count()));
 17 
 18     // 線程開始運(yùn)行
 19     m_bRunning = true;
 20 
 21     set_status(TH_READY);
 22 
 23     while(true){
 24         // Block until this thread is the leader.
 25         become_leader();
 26 
 27         // 設(shè)置線程空閑時(shí)間,空閑線程將會(huì)自動(dòng)退出
 28         ACE_Time_Value tv(ScheduleTime);
 29         tv += ACE_OS::gettimeofday();
 30 
 31         // 從隊(duì)列獲取下一個(gè)請(qǐng)求,并獲得所有權(quán)
 32         auto_ptr<ACE_Method_Request> request(m_activation_queue_.dequeue(&tv));
 33         if( request.get() == 0 ){                                               // 長(zhǎng)時(shí)間沒有請(qǐng)求,dequeue超時(shí)返回
 34             if( elect_new_leader() == 0 && thr_count() > MinThreadNum )         // 成功選擇新的領(lǐng)導(dǎo)者,且工作線程數(shù)大于最少線程數(shù)
 35                 break;                                                          // 結(jié)束當(dāng)前線程
 36             if( thr_count() < MinThreadNum && thr_count() < MaxThreadNum )      // 工作線程數(shù)小于最少線程數(shù),創(chuàng)建新的線程
 37                 _fork_new_thread();
 38             continue;                                                           // 繼續(xù)擔(dān)當(dāng)領(lǐng)導(dǎo)者(優(yōu)先成為領(lǐng)導(dǎo)者),或返回線程池等待
 39         }
 40 
 41         // Elect a new leader then process the request
 42         if( elect_new_leader() != 0 || thr_count() < MinThreadNum )             // 沒有空余線程可成為領(lǐng)導(dǎo)者,或者線程池容量調(diào)整
 43             if!m_bShutdown )                                                  // 且沒有調(diào)度關(guān)閉
 44                 if( thr_count() < MaxThreadNum )                                // 未達(dá)到線程數(shù)上線
 45                     _fork_new_thread();                                         // 創(chuàng)建新的線程
 46 
 47         // Invoke the method request.
 48         set_status(TH_WORKER);
 49 
 50         ACE_Time_Value tv_start,tv_finish,tv_working;
 51         tv_start = ACE_OS::gettimeofday();
 52 
 53         int result = request->call();
 54 
 55         tv_finish = ACE_OS::gettimeofday();
 56         tv_working = tv_finish - tv_start;
 57         set_worktime(tv_working);
 58 
 59         if( result == -1 ){
 60             if( thr_count() > 1 )                                                // If received a ExitMethod, Notify the next Thread(if exists) to exit too.
 61                 _post_exit_request();
 62             break;
 63         }
 64     }
 65 
 66     // 剩下最后一個(gè)線程,線程池停止
 67     if( thr_count() == 1 )
 68         m_bRunning = false;
 69 
 70     set_status(TH_STOP);
 71     ACE_DEBUG((LM_ERROR, ACE_TEXT("(%t) Thread stoped.\t: %d working threads left.\n"),thr_count()-1));
 72     return 0;
 73 }
 74 
 75 int LF_ThreadPool::start_stread_pool( void )
 76 {
 77     m_bShutdown = false;
 78     return activate(THR_NEW_LWP| THR_JOINABLE,MinThreadNum);
 79 }
 80 
 81 int LF_ThreadPool::stop_thread_pool( void )
 82 {
 83     // 線程池已停止
 84     if!m_bRunning )
 85         return 0;
 86 
 87     m_bShutdown = true;
 88     _post_exit_request();
 89     return wait();
 90 }
 91 
 92 int LF_ThreadPool::post_request( ACE_Method_Request *request )
 93 {
 94     ACE_TRACE (ACE_TEXT ("SvcThreadPool::enqueue"));
 95     return m_activation_queue_.enqueue (request);
 96 }
 97 
 98 int LF_ThreadPool::_fork_new_thread( void )
 99 {
100     return activate(THR_NEW_LWP| THR_JOINABLE,1,1);
101 }
102 
103 int LF_ThreadPool::_post_exit_request( void )
104 {
105     return post_request(new ExitRequest);
106 }
107 

      怎么樣?很簡(jiǎn)單吧?什么?怎么用?Oh My Lady GaGa!還是告訴你吧:
1 m_pool.post_request(new M2M_EventRequest(m_lua_svc,m_lua_scripts,type_name,xml_event,*iter));
      需要線程池出來(lái)干活的時(shí)候,創(chuàng)建一個(gè)請(qǐng)求對(duì)象,扔給他就行了!

      好了,代碼就是最好的文檔,C++開源社區(qū)給了我成長(zhǎng)的土壤,希望能對(duì)后來(lái)者有所幫助。
      把這些東西貼出來(lái),是為了整理自己的大腦,免得這些曾經(jīng)頂著熊貓眼熬出來(lái)的東西,塵封在茫茫的代碼海洋中,取之于前輩,還之于后人。也希望有更多的高手能夠慷慨布道,壯大我們的C++社區(qū)。
posted on 2011-02-28 15:46 風(fēng)雷九州 閱讀(4279) 評(píng)論(3)  編輯 收藏 引用

FeedBack:
# re: 一個(gè)基于ACE的負(fù)載自適應(yīng)萬(wàn)能線程池實(shí)現(xiàn) 2011-02-28 17:25 true
常見的一種需求:把一個(gè)客戶端的處理始終綁定到某一個(gè)線程,就是說(shuō)各個(gè)請(qǐng)求之間是有時(shí)序要求的。線程池的自適應(yīng)要考慮一下這個(gè)問題  回復(fù)  更多評(píng)論
  
# re: 一個(gè)基于ACE的負(fù)載自適應(yīng)萬(wàn)能線程池實(shí)現(xiàn) 2011-02-28 17:49 風(fēng)雷九州
@true

嗯,這個(gè)當(dāng)初也有考慮到,是為了線程的上下文緩存盡量少切換,在數(shù)據(jù)處理中為了充分發(fā)揮CPU的緩存性能,還需要考慮線程的優(yōu)先執(zhí)行CPU等。

這些措施在性能要求十分苛刻的情況下時(shí)必須要考慮的,我的方案目前僅是實(shí)現(xiàn)了客戶端請(qǐng)求與線程的分離,使程序的架構(gòu)更靈活,能夠滿足一般的服務(wù)器并發(fā)性能要求即可。

@true

我理解錯(cuò)了,你說(shuō)的可能是,需求要求客戶端的請(qǐng)求是有固定的時(shí)序的,但是我的方案并不是用來(lái)處理客戶端并發(fā)的,線程池處理的是大量的設(shè)備消息,這些消息通常大量并發(fā)到達(dá),而且相互之間沒有什么關(guān)系,故不需要某個(gè)特定的線程來(lái)處理。

設(shè)備的狀態(tài)是保存在單獨(dú)的狀態(tài)服務(wù)中的的,任何一個(gè)線程接到處理任務(wù)都能夠處理設(shè)備的狀態(tài)邏輯,多線程之間是通過“讀寫鎖”共享狀態(tài)服務(wù)的。

除非是考慮到線程執(zhí)行上下文切換的代價(jià)帶來(lái)的性能損失,否則邏輯上是不關(guān)心某個(gè)請(qǐng)求是被哪個(gè)線程處理的。  回復(fù)  更多評(píng)論
  
# re: 一個(gè)基于ACE的負(fù)載自適應(yīng)萬(wàn)能線程池實(shí)現(xiàn) 2011-02-28 22:19 liquanhai
非常感謝,學(xué)習(xí)了  回復(fù)  更多評(píng)論
  

只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。
網(wǎng)站導(dǎo)航: 博客園   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>
              欧美日韩亚洲成人| 欧美一区二区三区视频在线观看| 卡一卡二国产精品| 亚洲精品久久久蜜桃| 亚洲日本欧美| 欧美日韩精品一二三区| 亚洲已满18点击进入久久| 亚洲视频专区在线| 国内精品久久久久影院薰衣草| 久久伊人一区二区| 猛男gaygay欧美视频| 亚洲免费精品| 午夜影院日韩| 亚洲另类黄色| 亚洲一区在线播放| 精品动漫av| 99亚洲精品| 国内揄拍国内精品少妇国语| 亚洲国产影院| 国产欧美一区二区三区沐欲| 你懂的国产精品| 欧美精选在线| 久久久五月婷婷| 欧美精品一区二区蜜臀亚洲 | 久久女同互慰一区二区三区| 日韩视频一区二区三区| 亚洲一区二区三区精品在线 | 欧美久久影院| 久久gogo国模裸体人体| 欧美电影在线播放| 久久精品国产v日韩v亚洲 | 久久九九国产精品| 亚洲午夜一区| 老司机亚洲精品| 亚洲欧美一区二区视频| 欧美成人r级一区二区三区| 西西裸体人体做爰大胆久久久| 久久亚洲影院| 欧美一区亚洲一区| 欧美日韩一区二区三区视频| 欧美成人免费在线观看| 国产区二精品视| 亚洲黄色在线视频| 亚洲国产91色在线| 久久久久久免费| 午夜在线一区| 国产精品美女999| 亚洲日本激情| 亚洲精品影视| 美女主播一区| 久久亚洲视频| 欧美成人精品在线| 国产在线精品成人一区二区三区| 99国产精品久久久| 亚洲狼人精品一区二区三区| 久久久一区二区| 久久五月婷婷丁香社区| 国产欧美高清| 亚洲欧美福利一区二区| 亚洲欧美www| 国产精品啊啊啊| 中日韩在线视频| 亚洲在线中文字幕| 国产精品剧情在线亚洲| 一区二区三区国产盗摄| 亚洲视频免费| 国产精品免费一区二区三区在线观看 | 久久精品国产2020观看福利| 久久精品亚洲一区二区| 国内精品免费在线观看| 久久精品国产欧美激情| 久久综合中文色婷婷| 国语自产精品视频在线看一大j8| 欧美一级视频| 久久嫩草精品久久久精品一| 韩国三级在线一区| 老司机成人在线视频| 亚洲精品国产欧美| 亚洲一区二区三区激情| 国产精品一区久久久久| 久久成人18免费观看| 欧美高清视频在线| 亚洲视频免费| 国产欧美日韩亚洲精品| 久久久精品久久久久| 亚洲国产天堂久久国产91| 一道本一区二区| 国产精品色婷婷| 久久久久国产精品一区| 亚洲激情亚洲| 亚洲欧美韩国| 一区二区三区在线高清| 欧美精品v日韩精品v韩国精品v| 日韩午夜av电影| 久久久噜噜噜久久久| 夜夜嗨av一区二区三区四季av | 久久精品亚洲精品| 亚洲精品1234| 欧美一级欧美一级在线播放| 在线观看欧美激情| 欧美手机在线| 久久躁日日躁aaaaxxxx| 99精品欧美| 女人天堂亚洲aⅴ在线观看| 在线亚洲一区二区| 狠狠做深爱婷婷久久综合一区 | 国产亚洲欧美在线| 欧美精品一区二区三区视频| 麻豆精品传媒视频| 亚洲综合首页| 性久久久久久久| 亚洲国产精品久久久久| 国产精品手机视频| 欧美丰满高潮xxxx喷水动漫| 亚洲午夜久久久| 久久亚洲不卡| 亚洲综合日韩| 日韩视频在线免费| 在线精品视频在线观看高清| 国产精品日韩精品欧美在线| 欧美国产日韩视频| 久久美女性网| 久久精品国产免费| 先锋影音网一区二区| 99精品热6080yy久久| 亚洲国产天堂久久国产91| 狼狼综合久久久久综合网| 午夜欧美大尺度福利影院在线看 | 狠狠色伊人亚洲综合成人| 欧美激情视频在线播放| 久久成人国产| 久久成人人人人精品欧| 亚洲淫片在线视频| 亚洲网友自拍| 一区二区三区|亚洲午夜| 亚洲精品国久久99热| 亚洲国产精品一区在线观看不卡| 久久成人一区| 久久激情网站| 久久成人av少妇免费| 欧美诱惑福利视频| 午夜国产精品视频| 香蕉av福利精品导航| 欧美在线一区二区三区| 99国内精品| 一区二区高清在线观看| 亚洲午夜国产一区99re久久| 一本色道久久| 亚洲欧美综合| 久久精品国产精品| 久久久精品动漫| 久久一区国产| 亚洲国产精品女人久久久| 亚洲国产成人精品女人久久久| 欧美成人精品一区| 亚洲三级免费观看| 亚洲激情视频在线观看| 亚洲人成人一区二区三区| 一本色道精品久久一区二区三区| 一本久久综合亚洲鲁鲁五月天| 亚洲午夜激情网页| 欧美一区二区三区视频| 久久久精品一区| 免费在线观看一区二区| 欧美日本韩国一区| 国产精品网曝门| 在线观看日韩国产| 亚洲视频久久| 性刺激综合网| 亚洲天堂第二页| 久久久亚洲高清| 亚洲电影在线观看| 亚洲一区二区三区国产| 久久精品官网| 欧美色欧美亚洲高清在线视频| 国产精品美女久久久免费| 亚洲国产欧美久久| 午夜精品成人在线| 亚洲第一区在线| 亚洲欧美精品| 欧美激情在线观看| 国产在线日韩| 亚洲尤物影院| 欧美大片免费看| 亚洲欧美日韩一区二区| 欧美大胆a视频| 国产一区二区电影在线观看 | 亚洲高清免费在线| 亚洲欧美日韩另类精品一区二区三区| 久久久水蜜桃av免费网站| 亚洲免费av电影| 午夜精品久久久久久99热软件| 久久精品国产欧美激情| 国产精品女人久久久久久| 亚洲精品影视| 欧美国产精品日韩| 亚洲欧美日韩国产综合在线| 欧美96在线丨欧| 伊人久久亚洲美女图片| 欧美在线一区二区|