国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 學(xué)院 > 開(kāi)發(fā)設(shè)計(jì) > 正文

[CLR via C#]25. 線程基礎(chǔ)

2019-11-17 03:17:14
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

[CLR via C#]25. 線程基礎(chǔ)

一、Windows為什么要支持線程

  Microsoft設(shè)計(jì)OS內(nèi)核時(shí),他們決定在一個(gè)進(jìn)程(
  • 線程內(nèi)核對(duì)象(thread kernel object) OS為系統(tǒng)中創(chuàng)建的每個(gè)線程都分配并初始化這種數(shù)據(jù)結(jié)構(gòu)。在該數(shù)據(jù)結(jié)構(gòu)中,包含一組對(duì)線程進(jìn)行描述的屬性。數(shù)據(jù)結(jié)構(gòu)中還包含所謂的線程上下文(thead context)。上下文是一個(gè)內(nèi)存塊,其中包含了CPU的寄存器集合。Windows在一臺(tái)x86CPU的計(jì)算機(jī)運(yùn)行時(shí),線程上下文使用約700字節(jié)的內(nèi)存。對(duì)于x64和IA64CPU,上下文分別使用約1240字節(jié)和2500字節(jié)的內(nèi)存。
  • 線程環(huán)境塊(thread environment block,TEB) TEB是在用戶模式中分配和初始化的一個(gè)內(nèi)存塊。TEB耗用1個(gè)內(nèi)存頁(yè)(x86和x64CPU中是4KB,IA64CPU中是8K)。TEB包含線程的異常處理鏈?zhǔn)住>€程進(jìn)入的每個(gè)try塊都在鏈?zhǔn)撞迦胍粋€(gè)節(jié)點(diǎn)。線程退出try塊時(shí),會(huì)從鏈中刪除該節(jié)點(diǎn)。除此之外,TEB還包括線程的"線程本地存儲(chǔ)"數(shù)據(jù),以及由GDI和OpenGL圖形使用的一些數(shù)據(jù)結(jié)構(gòu)。
  • 用戶模式棧(user-mode stack) 用戶模式棧用于存儲(chǔ)傳給方法的局部變量和實(shí)參。它還包含一個(gè)地址:指向當(dāng)前方法返回時(shí),應(yīng)該接著從哪個(gè)地址開(kāi)始執(zhí)行。默認(rèn)情況下,Windows為每個(gè)線程的用戶模式分配1MB的內(nèi)存。
  • 內(nèi)核模式棧(kernel-model stack) 應(yīng)用程序代碼向OS中的一個(gè)內(nèi)核模式的函數(shù)傳遞實(shí)參時(shí),會(huì)使用內(nèi)核模式棧。出于安全方面的原因,針對(duì)從用戶模式的代碼傳給內(nèi)核的任何實(shí)參,Windows都會(huì)把它們從線程的用戶模式棧復(fù)制到線程的內(nèi)核模式棧。一經(jīng)復(fù)制,內(nèi)核就可以驗(yàn)證實(shí)參的值,然后進(jìn)行處理。除此之外,內(nèi)核會(huì)調(diào)用它自己內(nèi)部的方法,并利用內(nèi)核模式棧傳遞自己的實(shí)參、存儲(chǔ)函數(shù)的局部變量以及存儲(chǔ)返回地址。在32為的Windows運(yùn)行時(shí),內(nèi)核模式棧大小為12KB;在64位Windows上運(yùn)行時(shí),大小為24KB。
  • DLL線程連接(attach)和線程分離(detach)通知Windows的一個(gè)策略是,任何時(shí)候在進(jìn)程中創(chuàng)建一個(gè)線程,都會(huì)調(diào)用那個(gè)進(jìn)程中加載的所有DLL的DLLMain方法,并向該方法傳遞一個(gè)DLL_THREAD_ATTACH標(biāo)識(shí)。類似的,任何時(shí)候一個(gè)線程終止,都會(huì)調(diào)用進(jìn)程中的所有DLL的DLLMain方法,并向該方法傳遞一個(gè)DLL_THREAD_DETACH標(biāo)識(shí)。有的DLL需要利用這些通知,為進(jìn)程中創(chuàng)建和銷毀的每個(gè)線程執(zhí)行一些特殊的初始化或資源清理操作。
  •   現(xiàn)在,你已經(jīng)知道了創(chuàng)建線程、讓它進(jìn)駐系統(tǒng)以及最后銷毀它所需要的全部空間和時(shí)間的開(kāi)銷。現(xiàn)在我們開(kāi)始討論上下文切換。  單CPU的計(jì)算機(jī)一次只能做一件事。所以,Windows必須在系統(tǒng)中的所有線程之間共享物理CPU。  在任意時(shí)刻,Windows只將一個(gè)線程分配給一個(gè)CPU。那個(gè)線程允許運(yùn)行一個(gè)"時(shí)間片"。一旦時(shí)間片到期,Windows將上下文切換到另一個(gè)線程,每次上下文切換都要求Windows執(zhí)行以下操作。
    • 將CPU寄存器中的值保存到當(dāng)前正在運(yùn)行的線程的內(nèi)核對(duì)象內(nèi)部的一個(gè)上下文結(jié)構(gòu)中。
    • 從現(xiàn)有線程集合中選出一個(gè)線程供調(diào)度(這個(gè)就是要切換到的線程)。如果該線程由另一個(gè)進(jìn)程擁有,Windows在開(kāi)始執(zhí)行任何代碼或者任何數(shù)據(jù)之前,還必須切換CPU"看見(jiàn)"的虛擬地址空間。
    • 將所選上下文結(jié)構(gòu)中的值加載到CPU的寄存器中。
      上下文切換完成后,CPU執(zhí)行所選的線程,直到它的時(shí)間片到期。然后,會(huì)發(fā)生另一次上下文切換。Windows大約每30毫秒執(zhí)行一次上下文切換。上下文切換是凈開(kāi)銷;也就是說(shuō),上下文切換所產(chǎn)生的開(kāi)銷不會(huì)換來(lái)任何內(nèi)存或性能上的收益。Windows執(zhí)行上下文切換,向用戶提供一個(gè)健壯的、響應(yīng)靈敏的
    操作系統(tǒng)。  事實(shí)上,上下文切換對(duì)性能的影響可能超出你的想象。CPU現(xiàn)在是要執(zhí)行一個(gè)不同的線程,而之前的線程代碼和數(shù)據(jù)還保存在CPU的高速緩存中,這使CPU不必進(jìn)程訪問(wèn)RAM。當(dāng)Windows上下文切換到一個(gè)新的線程時(shí),這個(gè)新線程極有可能要執(zhí)行不同的代碼和數(shù)據(jù),這些數(shù)據(jù)不再CPU的高速緩存中,因此,CPU必須訪問(wèn)RAM來(lái)填充它的高速緩存,以恢復(fù)告訴執(zhí)行狀態(tài)。但是,在30毫秒之后,一次新的上下文切換又發(fā)生了。  除此之外,執(zhí)行垃圾回收時(shí),CLR必須掛起所有線程,遍歷它們的棧來(lái)查找根以便對(duì)堆中的對(duì)象進(jìn)行標(biāo)記,再次遍歷它們的棧,再次恢復(fù)所有線程。所以,減少線程的數(shù)量也會(huì)顯著提升垃圾回收器的功能。  根據(jù)上述討論,我們的結(jié)論是必須盡可能地避免使用線程,因?yàn)樗鼈円挠么罅績(jī)?nèi)存,而且需要相當(dāng)多的時(shí)間來(lái)創(chuàng)建、銷毀和關(guān)聯(lián)。WIndows在進(jìn)行上下文切換,以及垃圾回收時(shí)也會(huì)浪費(fèi)更多的時(shí)間。但是不可否認(rèn),因?yàn)椴攀荳indows變得更健壯,反應(yīng)更靈敏。  應(yīng)該指出,安裝多個(gè)CPU的計(jì)算機(jī)可以真正同時(shí)允許幾個(gè)線程,這提升應(yīng)用程序的可伸縮性(在更少的時(shí)間內(nèi)做更多的事)。Windows為每個(gè)CPU內(nèi)核都分配一個(gè)線程,每個(gè)內(nèi)核都自己執(zhí)行到其他線程的上下文切換。Windows確保單個(gè)線程不會(huì)同時(shí)在多個(gè)內(nèi)核上調(diào)度。三、停止瘋狂  如果追求性能,那么任何計(jì)算機(jī)最優(yōu)的線程數(shù)就是那臺(tái)計(jì)算機(jī)的CPU個(gè)數(shù)。如果線程數(shù)超過(guò)了CPU的個(gè)數(shù)那么就會(huì)發(fā)生線程上下文切換和性能損失。  在Windows中,創(chuàng)建一個(gè)進(jìn)程的代價(jià)是昂貴的。創(chuàng)建一個(gè)進(jìn)程通常要花幾秒鐘的時(shí)間,必須分配大量的內(nèi)存,這些內(nèi)存必須初始化,EXE和DLL文件必須從磁盤(pán)上加載等等。相反,在Windows創(chuàng)建線程是十分廉價(jià)的。所以,開(kāi)發(fā)人員決定停止創(chuàng)建進(jìn)程,改為創(chuàng)建線程。這就是我們看到有這么多線程的原因。但是,線程相對(duì)于其它系統(tǒng)資源還是比較昂貴的,所以還是應(yīng)該省著用。  必須承認(rèn),系統(tǒng)中的大多數(shù)線程都是本地代碼創(chuàng)建的。所以,線程的用戶模式棧僅僅保留(預(yù)定)地址空間,而且極有可能沒(méi)有完全提交來(lái)獲取物理內(nèi)存。然而,隨著越來(lái)越多的應(yīng)用程序成為托管應(yīng)用程序,或者在其中運(yùn)行托管組件,會(huì)有越來(lái)越多的棧被完全提交,會(huì)真實(shí)的分配到1MB的物理內(nèi)存。無(wú)論如何,即使拋開(kāi)用戶模式棧不談,所有線程仍然會(huì)分配到內(nèi)核模式棧以及其它資源。這種覺(jué)得線程十分廉價(jià)便胡亂創(chuàng)建線程的勢(shì)頭必須停止。四、CLR線程和Windows線程  CLR現(xiàn)在用的是Windows的線程處理能力。  雖然現(xiàn)在CLR線程直接對(duì)應(yīng)一個(gè)Windows線程,但Microsoft CLR團(tuán)隊(duì)保留了將來(lái)把它從Windows線程中分離的權(quán)限。有一天,CLR可能引入它自己的邏輯線程概念,使一個(gè)CLR邏輯線程并非一定映射到一個(gè)物理Windows線程。據(jù)說(shuō),邏輯線程將使用比物理線程少的多的資源,所以能在極少量的物理線程上運(yùn)行大量的邏輯線程。五、使用專用線程執(zhí)行異步的計(jì)算限制操作  本節(jié)將展示如何創(chuàng)建一個(gè)線程,并讓它執(zhí)行一次異步計(jì)算限制操作。雖然會(huì)教你具體如何做,但是強(qiáng)烈建議你避免采用這里展示的技術(shù)。相反,應(yīng)該盡量使用CLR的線程池來(lái)執(zhí)行異步計(jì)算限制操作,具體以后會(huì)討論。  如果執(zhí)行的代碼要求處于一種特定的狀態(tài),而這種狀態(tài)對(duì)于線程池的線程來(lái)說(shuō)是非比尋常的,就可以考慮創(chuàng)建一個(gè)線程 。例如,滿足以下任意一個(gè)條件,就可以顯式創(chuàng)建自己的線程。
    • 線程需要以非普通線程優(yōu)先級(jí)運(yùn)行。所有線程池線程都以普通優(yōu)先級(jí)運(yùn)行;雖然可以改變這種優(yōu)先級(jí),但不建議這樣做。另外,在不同的線程池操作之間,對(duì)優(yōu)先級(jí)的更改是無(wú)法持續(xù)的。
    • 需要線程表現(xiàn)為一個(gè)前臺(tái)線程,防止應(yīng)用程序在線程結(jié)束它的任務(wù)之前終止。線程池的線程都是后臺(tái)線程。如果CLR想要終止線程,它們可能被迫無(wú)法完成任務(wù)。
    • 一個(gè)計(jì)算限制的任務(wù)需要長(zhǎng)時(shí)間運(yùn)行。線程池為了判斷是否需要?jiǎng)?chuàng)建一個(gè)額外的線程,所采用的邏輯是比較復(fù)雜的。直接為長(zhǎng)時(shí)間運(yùn)行的任務(wù)創(chuàng)建一個(gè)專用線程,則可以避免這個(gè)問(wèn)題。
    • 要啟動(dòng)一個(gè)線程,并可能調(diào)用Thread的Abort方法來(lái)提前終止它。
    為了創(chuàng)建一個(gè)專用線程,要構(gòu)造System.Thearding.Thread類的一個(gè)實(shí)例,向它的構(gòu)造器傳遞一個(gè)方法的的名稱。以下是Thread構(gòu)造器的原型:
    public sealed class Thread : CriticalFinalizerobject,... {    public Thread(ParameterizedThreadStart start);    //這里沒(méi)有列出不常用的構(gòu)造器}

      start參數(shù)標(biāo)識(shí)專用線程要執(zhí)行的方法,這個(gè)方法必須和ParameterizedThreadStart委托的簽名匹配。

    delegate void ParameterizedThreadStart(Oject obj);
      構(gòu)造Thread對(duì)象是一個(gè)輕量級(jí)操作,因?yàn)樗⒉粚?shí)際創(chuàng)建一個(gè)操作系統(tǒng)線程。要實(shí)際創(chuàng)建操作系統(tǒng)線程,并讓它開(kāi)始執(zhí)行回調(diào)方法,必須調(diào)用Thread的Start方法,向它傳遞要作為回調(diào)方法的實(shí)參傳遞的對(duì)象(狀態(tài))。以下代碼演示了如何創(chuàng)建一個(gè)專用線程,并讓它異步調(diào)用一個(gè)方法:
    internal static class FirstThread {   public static void Go() {      Console.WriteLine("Main thread: starting a dedicated thread " +         "to do an asynchronous Operation");      Thread dedicatedThread = new Thread(ComputeBoundOp);      dedicatedThread.Start(5);       Console.WriteLine("Main thread: Doing other work here...");      Thread.Sleep(10000);     // 模擬做其它工作(10 秒鐘)       dedicatedThread.Join();  // 等待線程終止      Console.ReadLine();   }    // 這個(gè)方法的前面必須和ParametizedThreadStart委托匹配   private static void ComputeBoundOp(Object state) {      // 這個(gè)方法由一個(gè)專用線程執(zhí)行      Console.WriteLine("In ComputeBoundOp: state={0}", state);      Thread.Sleep(1000);  // 模擬其它任務(wù)(1 秒鐘)       // 這個(gè)方法返回后,專用線程將終止   }}
      在我的機(jī)器上編譯運(yùn)行,可能得到以下結(jié)果:Main thread: starting a dedicated thread to do an asynchronous operationMain thread: Doing other work here...In ComputeBoundOp: state=5  但有的時(shí)候運(yùn)行上述代碼,也可能得到以下結(jié)果,因?yàn)槲覠o(wú)法控制Windows對(duì)兩個(gè)線程進(jìn)行調(diào)度的方式:Main thread: starting a dedicated thread to do an asynchronous operationIn ComputeBoundOp: state=5Main thread: Doing other work here...  注意Go()方法調(diào)用的Join。Join方法造成調(diào)用線程阻塞當(dāng)前執(zhí)行的任何代碼,直到dedicatedThread所代表的那個(gè)線程銷毀或終止。六、使用線程的理由使用線程有以下三方面的理由:
    • 可以使用線程將代碼同其他代碼隔離這將提高應(yīng)用程序的可靠性。事實(shí)上,這正是Windows在操作系統(tǒng)中引入線程概念的原因。
    • 可以使線程來(lái)簡(jiǎn)化編碼有的時(shí)候,如果通過(guò)一個(gè)任務(wù)自己的線程來(lái)執(zhí)行該任務(wù),編碼會(huì)變得更簡(jiǎn)單。通常,在你引入線程時(shí),引入的是要相互協(xié)作的代碼,它們可能要求線程同步構(gòu)造知道另一個(gè)線程在什么時(shí)候終止。一旦開(kāi)始涉及協(xié)作,就要使用更多的資源,同時(shí)會(huì)使代碼變得更復(fù)雜。所以,在開(kāi)發(fā)使用線程之前,務(wù)必確定線程真的能幫到你。
    • 可以用線程來(lái)實(shí)現(xiàn)并發(fā)處理如果知道自己的應(yīng)用程序要在多CPU機(jī)器上運(yùn)行,那么讓多個(gè)任務(wù)同時(shí)運(yùn)行,就能提高性能。
    七、線程調(diào)度和優(yōu)先級(jí)  搶占式(preemptive)操作系統(tǒng)必須使用某種算法判斷在什么時(shí)候調(diào)度哪些線程多長(zhǎng)時(shí)間。本節(jié)討論Windows采用的算法。在前面,已經(jīng)提到過(guò)每個(gè)線程的內(nèi)核對(duì)象都包含一個(gè)上下文結(jié)構(gòu)。上下文結(jié)構(gòu)反映了當(dāng)線程上一次執(zhí)行時(shí),線程的CPU寄存器的狀態(tài)。在一個(gè)時(shí)間片之后,Windows檢查現(xiàn)有的所有線程內(nèi)存對(duì)象。在這些對(duì)象中,只有那些沒(méi)有正在等待什么的線程才適合調(diào)度。      Windows選擇一個(gè)可調(diào)度的線程內(nèi)核對(duì)象,并上下文切換到它。Windows實(shí)際記錄了每個(gè)線程被上下文切換到的次數(shù)。可以使用向Microsoft Spy++這樣的工具查看這個(gè)數(shù)據(jù)。  Windows之所以被稱為一種搶占式多線程操作系統(tǒng),是因?yàn)榫€程可以在任何時(shí)間被停止(被搶占),并調(diào)度另一個(gè)線程。所以,你不能保證自己的線程一直在運(yùn)行,不能阻止其他線程的運(yùn)行。  每個(gè)線程都分配了從0(最低)—31(最高)的一個(gè)優(yōu)先級(jí)。系統(tǒng)決定將哪個(gè)線程分配給一個(gè)CPU時(shí),它首先檢查優(yōu)先級(jí)31的線程,并以一種輪流的方式調(diào)度它們。  只要存在可以調(diào)度的優(yōu)先級(jí)31的線程,系統(tǒng)永遠(yuǎn)不會(huì)將優(yōu)先級(jí)0-30的任何線程分配給CPU。這種情況稱為饑餓(starvation)。當(dāng)較高優(yōu)先級(jí)的線程占用了太多的CPU時(shí)間,致使較低優(yōu)先級(jí)的線程無(wú)法運(yùn)行時(shí),就會(huì)發(fā)生這種情況。在多處理器機(jī)器上饑餓發(fā)生的可能性要小得多,因?yàn)檫@種機(jī)器上優(yōu)先級(jí)31的線程和優(yōu)先級(jí)30的線程可以同時(shí)運(yùn)行。系統(tǒng)總是保持各CPU處于忙碌狀態(tài),只有沒(méi)有線程可調(diào)度的時(shí)候,CPU才空閑下來(lái)。  較高優(yōu)先級(jí)的線程總是搶占較低優(yōu)先級(jí)的線程,無(wú)論正在運(yùn)行的是什么較低優(yōu)先級(jí)的線程。  系統(tǒng)啟動(dòng)時(shí),會(huì)創(chuàng)建一個(gè)名為零頁(yè)線程的特殊線程。這個(gè)線程的優(yōu)先級(jí)定位0,而且整個(gè)系統(tǒng)中唯一一個(gè)優(yōu)先級(jí)為0的線程。零頁(yè)線程負(fù)責(zé)在么有其它線程需要執(zhí)行的時(shí)候,將系統(tǒng)的RAM的所有空閑頁(yè)清零。  設(shè)計(jì)應(yīng)用程序時(shí),應(yīng)決定自己的應(yīng)用程序是需要比機(jī)器上同時(shí)運(yùn)行的其它應(yīng)用程序更高還是更低的響應(yīng)能力。然后,選擇一個(gè)進(jìn)程優(yōu)先級(jí)類(priority class)來(lái)反映你的決定。Windows支持6個(gè)進(jìn)程優(yōu)先級(jí)類:Idle(空閑),Below Noral(低于標(biāo)準(zhǔn)),Normal(標(biāo)準(zhǔn)),Above Normal(高于標(biāo)準(zhǔn)),High(高)和Realtime(實(shí)時(shí))。由于Normal是默認(rèn)優(yōu)先級(jí)類,所以它是最常用的優(yōu)先級(jí)類。  優(yōu)先級(jí)類和優(yōu)先級(jí)是兩個(gè)不同的概念。根據(jù)定義,線程的優(yōu)先級(jí)取決于兩個(gè)標(biāo)準(zhǔn):1)它的進(jìn)程優(yōu)先級(jí)類 2)在其進(jìn)程的優(yōu)先級(jí)類中,線程的優(yōu)先級(jí)。進(jìn)程優(yōu)先級(jí)類和線程優(yōu)先級(jí)構(gòu)成了一個(gè)線程的"基礎(chǔ)優(yōu)先級(jí)"。注意,每個(gè)線程都有一個(gè)動(dòng)態(tài)優(yōu)先級(jí)。線程調(diào)度器是根據(jù)優(yōu)先級(jí)來(lái)決定運(yùn)行哪個(gè)線程。最初,線程的動(dòng)態(tài)優(yōu)先級(jí)適合基礎(chǔ)優(yōu)先級(jí)一樣的,系統(tǒng)可提升或降低動(dòng)態(tài)優(yōu)先級(jí),以確保它的響應(yīng),并避免現(xiàn)在在處理器時(shí)間內(nèi)"饑餓"。但是,基礎(chǔ)優(yōu)先級(jí)在16-31之間的優(yōu)先級(jí)線程,系統(tǒng)不會(huì)提升它們的優(yōu)先級(jí),在0-15優(yōu)先級(jí)之間的線程才會(huì)被動(dòng)提升優(yōu)先級(jí)。  如果一個(gè)應(yīng)用程序(比如屏幕保護(hù)程序),在系統(tǒng)什么事情都不做的時(shí)候運(yùn)行,就適合分配Idle優(yōu)先級(jí)類。一些執(zhí)行統(tǒng)計(jì)學(xué)跟蹤分析的應(yīng)用程序需要定期更新于體統(tǒng)有關(guān)的狀態(tài),這種應(yīng)用程序一般不應(yīng)該妨礙執(zhí)行更關(guān)鍵的任務(wù)。  只有在絕對(duì)必要的時(shí)候才應(yīng)使用High優(yōu)先級(jí)類。Realtime優(yōu)先級(jí)類要經(jīng)可能的避免。Realtime優(yōu)先級(jí)相當(dāng)高,它甚至可能干擾操作系統(tǒng)任務(wù),比如阻礙一些必要的磁盤(pán)I/O和網(wǎng)絡(luò)傳輸。  選好一個(gè)優(yōu)先級(jí)類后,就不要再思考你的應(yīng)用程序和其他應(yīng)用程序的關(guān)系了。現(xiàn)在,應(yīng)該將所有注意力放在應(yīng)用程序中的線程上。Windows支持7個(gè)相對(duì)線程優(yōu)先級(jí)Idle(空閑),Lowest(最低),Below Normal(低于標(biāo)準(zhǔn)),Normal(標(biāo)準(zhǔn)),Above Normal(高于標(biāo)準(zhǔn)),Highest(最高)和Time-Critical(關(guān)鍵時(shí)間(最高的相對(duì)線程優(yōu)先級(jí)))。這些優(yōu)先級(jí)相對(duì)于進(jìn)程優(yōu)先級(jí)類的。同樣的,由于Normal是默認(rèn)的相對(duì)線程優(yōu)先級(jí),所以最常用。這里并沒(méi)有提到有關(guān)0~31的優(yōu)先級(jí)的任何內(nèi)容。開(kāi)發(fā)者從來(lái)不用具體設(shè)置一個(gè)線程的優(yōu)先級(jí),也就是不需要將一個(gè)線程優(yōu)先級(jí)設(shè)置為0~31中的一個(gè)。操作系統(tǒng)負(fù)責(zé)將“優(yōu)先級(jí)類”和“相對(duì)線程優(yōu)先級(jí)”映射到一個(gè)具體的優(yōu)先級(jí)上。這種映射方式,是隨Windows版本的不同而不同的。
    1. <rt id="pj4qw"></rt>

        <noscript id="pj4qw"><dl id="pj4qw"></dl></noscript>
          發(fā)表評(píng)論 共有條評(píng)論
          用戶名: 密碼:
          驗(yàn)證碼: 匿名發(fā)表
          主站蜘蛛池模板: 曲松县| 井冈山市| 清河县| 龙州县| 呼玛县| 福鼎市| 揭阳市| 公安县| 五河县| 昌邑市| 贵州省| 东阳市| 西昌市| 凤山市| 礼泉县| 巫山县| 乌什县| 迭部县| 邵东县| 南靖县| 泗阳县| 宽甸| 余干县| 磴口县| 天峻县| 蒙城县| 沧州市| 射洪县| 河西区| 民丰县| 甘泉县| 岗巴县| 朝阳县| 长葛市| 湘阴县| 昆山市| 水城县| 濉溪县| 安阳县| 韶关市| 搜索|