最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Go語言中的定時(shí)器原理與實(shí)戰(zhàn)應(yīng)用

 更新時(shí)間:2024年10月14日 09:26:35   作者:景天科技苑  
在Go語言中,Timer和Ticker是處理定時(shí)任務(wù)的重要工具,Timer用于一次性事件,而Ticker則用于周期性事件,本文詳細(xì)介紹了這兩種定時(shí)器的創(chuàng)建、使用和停止方法,并通過實(shí)際案例展示了它們?cè)诒O(jiān)控日志、檢查系統(tǒng)狀態(tài)等方面的應(yīng)用

在Go語言中,定時(shí)器是并發(fā)編程中常用的工具之一。定時(shí)器可以用于監(jiān)控某個(gè)goroutine的運(yùn)行時(shí)間、定時(shí)打印日志、周期性執(zhí)行任務(wù)等多種場景。
Go標(biāo)準(zhǔn)庫提供了兩種主要的定時(shí)器:Timer(一次性定時(shí)器)和Ticker(周期性定時(shí)器)。本文將詳細(xì)介紹這兩種定時(shí)器的用法,并通過實(shí)際案例展示其應(yīng)用場景。

一、Timer定時(shí)器

Timer定時(shí)器是一種一次性定時(shí)器,即在未來某個(gè)時(shí)刻觸發(fā)的事件只會(huì)執(zhí)行一次。
Timer的結(jié)構(gòu)中包含一個(gè)Time類型的管道C,主要用于事件通知。
在未到達(dá)設(shè)定時(shí)間時(shí),管道內(nèi)沒有數(shù)據(jù)寫入,一直處于阻塞狀態(tài);到達(dá)設(shè)定時(shí)間后,會(huì)向管道內(nèi)寫入一個(gè)系統(tǒng)時(shí)間,觸發(fā)事件。

1. 創(chuàng)建Timer

使用time.NewTimer函數(shù)可以創(chuàng)建一個(gè)Timer定時(shí)器。該函數(shù)接受一個(gè)Duration類型的參數(shù),表示定時(shí)器的超時(shí)時(shí)間,并返回一個(gè)*Timer類型的指針。
看下源碼,Timer結(jié)構(gòu)體中,timer.C是一個(gè)時(shí)間類型的通道

在這里插入圖片描述

package main

import (
    "fmt"
    "time"
)

func main() {
    // func NewTimer(d Duration) *Timer
    timer := time.NewTimer(2 * time.Second) // 設(shè)置超時(shí)時(shí)間2秒
    // 先打印下當(dāng)前時(shí)間
    fmt.Println("當(dāng)前時(shí)間:", time.Now())

    //我們可以打印下這個(gè)只讀通道的值
        //timer.C就是我們?cè)诙x定時(shí)器的時(shí)候,存放的時(shí)間,等待對(duì)應(yīng)的時(shí)間?,F(xiàn)在這個(gè)就是根據(jù)當(dāng)前時(shí)間加2秒

    fmt.Println("通道里面的值", <-timer.C)
}

可以看到timer.C這個(gè)只讀通道里面的值,就是通過NewTimer設(shè)置時(shí)間間隔后的時(shí)間

在這里插入圖片描述

因此,我們可以根據(jù)時(shí)間通道,來定時(shí)將來某個(gè)時(shí)間要做的事

package main

import (
    "fmt"
    "time"
)

func main() {
    timer := time.NewTimer(2 * time.Second) // 設(shè)置超時(shí)時(shí)間2秒
    <-timer.C
    //經(jīng)過兩秒后只想下面代碼
    fmt.Println("after 2s Time out!")
}

在這里插入圖片描述

在上述代碼中,創(chuàng)建了一個(gè)超時(shí)時(shí)間為2秒的定時(shí)器,程序會(huì)阻塞在<-timer.C處,直到2秒后定時(shí)器觸發(fā),程序繼續(xù)執(zhí)行并打印“after 2s Time out!”。

2. 停止Timer

使用Stop方法可以停止一個(gè)Timer定時(shí)器。該方法返回一個(gè)布爾值,表示定時(shí)器是否在超時(shí)前被停止。
如果返回true,表示定時(shí)器在超時(shí)前被成功停止;如果返回false,表示定時(shí)器已經(jīng)超時(shí)或已經(jīng)被停止過。

在這里插入圖片描述

package main

import (
    "fmt"
    "time"
)

func main() {
    timer := time.NewTimer(2 * time.Second) // 設(shè)置超時(shí)時(shí)間2秒
    //這里,創(chuàng)建定時(shí)器后,里面執(zhí)行了停止方法,肯定是在定時(shí)器超時(shí)前停止了,返回true
    res := timer.Stop()
    fmt.Println(res) // 輸出:true
}

在上述代碼中,創(chuàng)建了一個(gè)超時(shí)時(shí)間為2秒的定時(shí)器,并立即調(diào)用Stop方法停止它。由于定時(shí)器還沒有超時(shí),所以Stop方法返回true。

3. 重置Timer

對(duì)于已經(jīng)過期或者是已經(jīng)停止的Timer,可以通過Reset方法重新激活它,并設(shè)置新的超時(shí)時(shí)間。Reset方法也返回一個(gè)布爾值,表示定時(shí)器是否在重置前已經(jīng)停止或過期。

在這里插入圖片描述

package main

import (
    "fmt"
    "time"
)

func main() {
    timer := time.NewTimer(2 * time.Second)
    <-timer.C
    fmt.Println("time out1")
    //經(jīng)過兩秒后,定時(shí)器超時(shí)了
    res1 := timer.Stop()
    //此時(shí)再stop,得到的是false
    fmt.Printf("res1 is %t\n", res1) // 輸出:false
    //然后我們重置定時(shí)器。重置成3秒后超時(shí)
    timer.Reset(3 * time.Second)
    res2 := timer.Stop()
    //此時(shí)再stop,由于定時(shí)器沒超時(shí),得到的是true
    fmt.Printf("res2 is %t\n", res2) // 輸出:true
}

在這里插入圖片描述

在上述代碼中,首先創(chuàng)建了一個(gè)超時(shí)時(shí)間為2秒的定時(shí)器,并在超時(shí)后打印“time out1”。
然后調(diào)用Stop方法停止定時(shí)器,由于定時(shí)器已經(jīng)過期,所以Stop方法返回false。
接著調(diào)用Reset方法將定時(shí)器重新激活,并設(shè)置新的超時(shí)時(shí)間為3秒。
最后再次調(diào)用Stop方法停止定時(shí)器,由于此時(shí)定時(shí)器還沒有過期,所以Stop方法返回true。

4. time.AfterFunc

time.AfterFunc函數(shù)可以接受一個(gè)Duration類型的參數(shù)和一個(gè)函數(shù)f,返回一個(gè)*Timer類型的指針。在創(chuàng)建Timer之后,等待一段時(shí)間d,然后執(zhí)行函數(shù)f。

package main

import (
    "fmt"
    "time"
)

func main() {
    duration := time.Duration(1) * time.Second
    f := func() {
        fmt.Println("f has been called after 1s by time.AfterFunc")
    }
    // func AfterFunc(d Duration, f func()) *Timer
    //等待duration時(shí)間后,執(zhí)行f函數(shù)
    //這里是經(jīng)過1秒后。執(zhí)行f函數(shù)
    timer := time.AfterFunc(duration, f)
    defer timer.Stop()
    time.Sleep(2 * time.Second)
}

在上述代碼中,創(chuàng)建了一個(gè)超時(shí)時(shí)間為1秒的定時(shí)器,并在超時(shí)后執(zhí)行函數(shù)f。
使用defer語句確保在程序結(jié)束時(shí)停止定時(shí)器。程序會(huì)在1秒后打印“f has been called after 1s by time.AfterFunc”。

5. time.After

time.After函數(shù)會(huì)返回一個(gè)*Timer類型的管道,該管道會(huì)在經(jīng)過指定時(shí)間段d后寫入數(shù)據(jù)。調(diào)用這個(gè)函數(shù)相當(dāng)于實(shí)現(xiàn)了一個(gè)定時(shí)器。

在這里插入圖片描述

package main

import (
    "fmt"
    "time"
)

func main() {
    ch := make(chan string)
    go func() {
        time.Sleep(3 * time.Second)
        ch <- "test"
    }()
    
    //使用select,哪個(gè)先到來,耗時(shí)時(shí)間短,執(zhí)行哪個(gè)
    select {
    case val := <-ch:
        fmt.Printf("val is %s\n", val)
    // 這個(gè)case是兩秒后執(zhí)行
    // func After(d Duration) <-chan Time
    case <-time.After(2 * time.Second):
        fmt.Println("timeout!!!")
    }
}

在這里插入圖片描述

在上述代碼中,創(chuàng)建了一個(gè)管道ch,并在另一個(gè)goroutine中等待3秒后向管道寫入數(shù)據(jù)。
在主goroutine中使用select語句監(jiān)聽兩個(gè)管道:一個(gè)是剛剛創(chuàng)建的ch,另一個(gè)是time.After函數(shù)返回的管道c。
由于ch管道3秒后才會(huì)有數(shù)據(jù)寫入,而time.After函數(shù)是2秒超時(shí),所以2秒后select會(huì)先收到管道c里的數(shù)據(jù),執(zhí)行“timeout!!!”并退出。

二、Ticker定時(shí)器

Ticker定時(shí)器可以周期性地不斷觸發(fā)時(shí)間事件,不需要額外的Reset操作。Ticker的結(jié)構(gòu)中也包含一個(gè)Time類型的管道C,每隔固定時(shí)間段d就會(huì)向該管道發(fā)送當(dāng)前的時(shí)間,根據(jù)這個(gè)管道消息來觸發(fā)事件。

Ticker定時(shí)器是Go標(biāo)準(zhǔn)庫time包中的一個(gè)重要組件。它允許你每隔一定的時(shí)間間隔執(zhí)行一次指定的操作。Ticker定時(shí)器在創(chuàng)建時(shí)會(huì)啟動(dòng)一個(gè)后臺(tái)goroutine,該goroutine會(huì)按照指定的時(shí)間間隔不斷向一個(gè)通道(Channel)發(fā)送當(dāng)前的時(shí)間值。

1. 創(chuàng)建Ticker

要?jiǎng)?chuàng)建一個(gè)Ticker定時(shí)器,你可以使用time.NewTicker函數(shù)。這個(gè)函數(shù)接受一個(gè)time.Duration類型的參數(shù),表示時(shí)間間隔,并返回一個(gè)*time.Ticker類型的指針。
Ticker定時(shí)器的核心是一個(gè)通道(Channel),你可以通過監(jiān)聽這個(gè)通道來接收時(shí)間間隔到達(dá)的事件。

ticker := time.NewTicker(1 * time.Second)

上面的代碼創(chuàng)建了一個(gè)每隔1秒觸發(fā)一次的Ticker定時(shí)器。

2. 監(jiān)聽Ticker事件

要監(jiān)聽Ticker定時(shí)器的事件,你可以使用range關(guān)鍵字或者select語句來監(jiān)聽Ticker定時(shí)器的通道。每次時(shí)間間隔到達(dá)時(shí),Ticker定時(shí)器的通道都會(huì)接收到一個(gè)當(dāng)前的時(shí)間值。

for range ticker.C {  
    // 在這里執(zhí)行周期性任務(wù)  
}
package main

import (
    "fmt"
    "time"
)

func main() {
    ticker := time.NewTicker(1 * time.Second)
    //查看定時(shí)器數(shù)據(jù)類型
    fmt.Printf("定時(shí)器數(shù)據(jù)類型%T\n", ticker)
    //啟動(dòng)協(xié)程來監(jiān)聽定時(shí)器觸發(fā)事件,通過time.Sleep函數(shù)來等待5秒鐘,然后調(diào)用ticker.Stop()函數(shù)來停止定時(shí)器。
    //最后,輸出"定時(shí)器停止"表示定時(shí)器已經(jīng)成功停止。
    go func() {
        for range ticker.C {
            fmt.Println("Ticker ticked")
        }

    }()

    //執(zhí)行5秒后,讓定時(shí)器停止
    time.Sleep(5 * time.Second)
    ticker.Stop()
    fmt.Println("定時(shí)器停止")
}

在這里插入圖片描述

或者,如果你需要同時(shí)監(jiān)聽多個(gè)通道,你可以使用select語句:

select {  
case t := <-ticker.C:  
    // 處理Ticker定時(shí)器事件  
case <-stopChan:  
    // 處理停止信號(hào)  
}
package main

import (
    "fmt"
    "time"
)

func main() {
    ticker := time.NewTicker(1 * time.Second) // 創(chuàng)建一個(gè)每秒觸發(fā)一次的Ticker定時(shí)器
    defer ticker.Stop()                       // 確保在main函數(shù)結(jié)束時(shí)停止定時(shí)器

    for {
        select {
        case t := <-ticker.C:
            fmt.Println("Tick at", t)
        }
    }
}

每秒執(zhí)行一次

在這里插入圖片描述

3. 停止Ticker定時(shí)器

當(dāng)你不再需要Ticker定時(shí)器時(shí),你應(yīng)該調(diào)用它的Stop方法來停止它。停止Ticker定時(shí)器可以釋放與之關(guān)聯(lián)的資源,并防止不必要的goroutine繼續(xù)運(yùn)行。
ticker.Stop()

停止Ticker定時(shí)器后,它的通道將不再接收任何事件。

package main

import (
    "fmt"
    "time"
)

func main() {
    ticker := time.NewTicker(500 * time.Millisecond) // 創(chuàng)建一個(gè)每500毫秒觸發(fā)一次的Ticker定時(shí)器
    timeEnd := make(chan bool)                       // 用于停止Ticker定時(shí)器的通道

    go func() {
        for {
            select {
            //當(dāng)達(dá)到設(shè)置的停止條件式,停止循環(huán)
            case <-timeEnd:
                fmt.Println("===結(jié)束任務(wù)")
                break
            case t := <-ticker.C:
                fmt.Println("==500毫秒響應(yīng)一次:", t)
            }
        }
    }()

    time.Sleep(5 * time.Second) // 主線程等待5秒鐘
    ticker.Stop()               // 停止Ticker定時(shí)器
    timeEnd <- true             // 發(fā)送結(jié)束信號(hào)

    fmt.Println("===定時(shí)任務(wù)結(jié)束===")
}

持續(xù)執(zhí)行5秒后,定時(shí)器停止運(yùn)行

在這里插入圖片描述

三、定時(shí)器應(yīng)用案例

1. 定時(shí)打印日志

Ticker定時(shí)器的一個(gè)常見應(yīng)用是定時(shí)打印日志。通過設(shè)置一個(gè)Ticker定時(shí)器,你可以每隔固定的時(shí)間間隔輸出一次日志信息,從而監(jiān)控程序的運(yùn)行狀態(tài)。

package main

import (
    "fmt"
    "time"
)

func main() {
    ticker := time.NewTicker(5 * time.Second)
    defer ticker.Stop() // 確保程序結(jié)束時(shí)停止Ticker定時(shí)器

    for range ticker.C {
        // 打印當(dāng)前時(shí)間作為日志
        fmt.Println("Current time:", time.Now())
    }
}

5秒打印一次

在這里插入圖片描述

在這個(gè)例子中,我們創(chuàng)建了一個(gè)每隔5秒觸發(fā)一次的Ticker定時(shí)器,并在一個(gè)無限循環(huán)中監(jiān)聽它的事件。
每次事件觸發(fā)時(shí),我們都會(huì)打印當(dāng)前的時(shí)間作為日志信息。注意,由于我們?cè)趍ain函數(shù)中使用了defer語句來確保Ticker定時(shí)器在程序結(jié)束時(shí)被停止,所以即使循環(huán)是無限的,程序也不會(huì)因?yàn)門icker定時(shí)器而泄漏資源。

然而,在實(shí)際應(yīng)用中,你可能需要在某個(gè)條件下提前停止Ticker定時(shí)器。這時(shí),你可以使用一個(gè)額外的通道來發(fā)送停止信號(hào):

package main

import (
    "fmt"
    "time"
)

func main() {
    ticker := time.NewTicker(5 * time.Second)
    stopChan := make(chan struct{})

    go func() {
        // 模擬一個(gè)運(yùn)行一段時(shí)間的任務(wù)
        time.Sleep(15 * time.Second)
        // 發(fā)送停止信號(hào)
        stopChan <- struct{}{}
    }()

    for {
        select {
        case t := <-ticker.C:
            fmt.Println("Tick at", t)
        case <-stopChan:
            fmt.Println("Ticker stopped")
            ticker.Stop()
            return
        }
    }
}

在這里插入圖片描述

在這個(gè)例子中,我們創(chuàng)建了一個(gè)額外的stopChan通道來發(fā)送停止信號(hào)。我們啟動(dòng)了一個(gè)goroutine來模擬一個(gè)運(yùn)行一段時(shí)間的任務(wù),并在任務(wù)完成后向stopChan發(fā)送一個(gè)停止信號(hào)。
在for循環(huán)中,我們使用select語句同時(shí)監(jiān)聽Ticker定時(shí)器的通道和stopChan通道。當(dāng)接收到停止信號(hào)時(shí),我們停止Ticker定時(shí)器并退出程序。

2. 周期性檢查系統(tǒng)狀態(tài)

Ticker定時(shí)器還可以用于周期性檢查系統(tǒng)狀態(tài)。例如,你可以每隔一段時(shí)間檢查一次服務(wù)器的負(fù)載、內(nèi)存使用情況或數(shù)據(jù)庫連接數(shù)等關(guān)鍵指標(biāo),并在發(fā)現(xiàn)異常時(shí)采取相應(yīng)的措施。

package main

import (
    "fmt"
    "math/rand"
    "time"
)

// 模擬檢查系統(tǒng)狀態(tài)的函數(shù)
func checkSystemStatus() {
    // 這里可以添加實(shí)際的檢查邏輯
    // 例如:檢查CPU使用率、內(nèi)存使用情況等
    // 這里我們隨機(jī)生成一個(gè)0到100之間的數(shù)作為模擬結(jié)果
    status := rand.Intn(101)
    fmt.Printf("System status: %d\n", status)

    // 假設(shè)狀態(tài)大于80表示系統(tǒng)異常
    if status > 80 {
        fmt.Println("Warning: System status is above normal!")
        // 這里可以添加處理異常的邏輯
        // 例如:發(fā)送警報(bào)、重啟服務(wù)等
    }
}

func main() {
    ticker := time.NewTicker(10 * time.Second)
    defer ticker.Stop() // 確保程序結(jié)束時(shí)停止Ticker定時(shí)器

    for range ticker.C {
        checkSystemStatus()
    }
}

在這里插入圖片描述

在這個(gè)例子中,我們創(chuàng)建了一個(gè)每隔10秒觸發(fā)一次的Ticker定時(shí)器,并在一個(gè)無限循環(huán)中監(jiān)聽它的事件。
每次事件觸發(fā)時(shí),我們都會(huì)調(diào)用checkSystemStatus函數(shù)來模擬檢查系統(tǒng)狀態(tài)。checkSystemStatus函數(shù)會(huì)隨機(jī)生成一個(gè)0到100之間的數(shù)作為模擬結(jié)果,并根據(jù)結(jié)果判斷是否系統(tǒng)異常。
如果系統(tǒng)異常(即狀態(tài)大于80),則打印警告信息,并可以在這里添加處理異常的邏輯。

同樣地,你可以使用額外的通道來發(fā)送停止信號(hào),以便在需要時(shí)提前停止Ticker定時(shí)器。

四、總結(jié)

本文詳細(xì)介紹了Go語言中Timer和Ticker兩種定時(shí)器的用法,并通過實(shí)際案例展示了它們的應(yīng)用場景。Timer定時(shí)器適用于需要一次性觸發(fā)的事件,而Ticker定時(shí)器適用于需要周期性觸發(fā)的事件

到此這篇關(guān)于Go語言中的定時(shí)器原理與實(shí)戰(zhàn)應(yīng)用的文章就介紹到這了,更多相關(guān)Go語言 定時(shí)器內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Go常問的一些面試題匯總(附答案)

    Go常問的一些面試題匯總(附答案)

    通常我們?nèi)ッ嬖嚳隙〞?huì)有些不錯(cuò)的Golang的面試題目的,所以總結(jié)下,讓其他Golang開發(fā)者也可以查看到,同時(shí)也用來檢測自己的能力和提醒自己的不足之處,這篇文章主要給大家介紹了關(guān)于Go常問的一些面試題以及答案的相關(guān)資料,需要的朋友可以參考下
    2023-10-10
  • Zed調(diào)試Go項(xiàng)目指南

    Zed調(diào)試Go項(xiàng)目指南

    本文主要介紹了Zed調(diào)試Go項(xiàng)目指南,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2026-06-06
  • go build和go install的區(qū)別介紹

    go build和go install的區(qū)別介紹

    這篇文章主要介紹了go build和go install的區(qū)別介紹,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2020-12-12
  • Go語言讀取文件的四種方式

    Go語言讀取文件的四種方式

    本文主要介紹了Go語言讀取文件的四種方式,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-04-04
  • 詳解Go channel管道的運(yùn)行原理

    詳解Go channel管道的運(yùn)行原理

    Go推薦通過通信來共享內(nèi)存,而channel就實(shí)現(xiàn)了這一理念。那channel是怎么運(yùn)行的呢?本文將帶你搞懂Go channel管道的運(yùn)行原理,感興趣的同學(xué)可以參考一下
    2023-05-05
  • Go語言使用PKCS12解析PFX文件的完整指南

    Go語言使用PKCS12解析PFX文件的完整指南

    在Go語言中解析PFX文件(?PKCS#12格式?)需使用?golang.org/x/crypto/pkcs12擴(kuò)展庫,該庫支持解析包含證書、私鑰和CA鏈的二進(jìn)制文件,以下是完整的解析指南與代碼示例,需要的朋友可以參考下
    2025-09-09
  • 淺談Golang數(shù)據(jù)競態(tài)

    淺談Golang數(shù)據(jù)競態(tài)

    本文主要介紹了淺談Golang數(shù)據(jù)競態(tài),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-02-02
  • go protobuf?詳解

    go protobuf?詳解

    Protobuf是Protocol Buffers的簡稱,它是Google公司開發(fā)的一種數(shù)據(jù)描述語言,是一種輕便高效的結(jié)構(gòu)化數(shù)據(jù)存儲(chǔ)格式,可以用于結(jié)構(gòu)化數(shù)據(jù)串行化,或者說序列化,這篇文章主要介紹了protobuf?詳解,需要的朋友可以參考下
    2024-01-01
  • Golang熔斷器的開發(fā)過程詳解

    Golang熔斷器的開發(fā)過程詳解

    Golang熔斷器是一種用于處理分布式系統(tǒng)中服務(wù)調(diào)用的故障保護(hù)機(jī)制,它可以防止故障服務(wù)的連鎖反應(yīng),提高系統(tǒng)的穩(wěn)定性和可靠性,本文將給大家詳細(xì)的介紹一下Golang熔斷器的開發(fā)過程,需要的朋友可以參考下
    2023-09-09
  • golang 之import和package的使用

    golang 之import和package的使用

    這篇文章主要介紹了golang 之import和package的使用,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2019-02-02

最新評(píng)論

胶州市| 芒康县| 清流县| 余姚市| 阿拉尔市| 玛曲县| 潼关县| 绥阳县| 隆尧县| 萨嘎县| 晋中市| 榆树市| 南平市| 云梦县| 乌鲁木齐县| 望城县| 龙山县| 浠水县| 沅江市| 砀山县| 木兰县| 娄烦县| 香格里拉县| 民丰县| 临朐县| 浑源县| 渝北区| 广东省| 偏关县| 桂林市| 岳西县| 犍为县| 崇礼县| 孟州市| 弥渡县| 信阳市| 高台县| 鄂伦春自治旗| 万全县| 宁安市| 驻马店市|