LoginSignup
5
7

More than 5 years have passed since last update.

goroutineを量産して様々な並列処理を行うための基盤づくり

Posted at

はじめに

Go言語の勉強し始めて2・3日のインフラエンジニアがなんとなく監視をテーマに選んで遊んで見る。

とりあえずやりたかったのは任意の数のgoroutineを生成すること。
そして今後の展望はその中で外部ファイルから読み込んだ任意の処理を行うこと。
監視用のエージェントをこんな感じにしたらどうかなーっていう試行錯誤の一旦です。

コード

Tickerと処理間隔、処理を終了させるためのchannelを構造体にまとめておく。
Textの部分は処理を簡単にする都合上適当に作っただけなので処理内容に合わせてなんか足す。

// MonTick : Structure for ticker and parameters.
type MonTick struct {
    Tick     *time.Ticker
    sec      int
    text     string
    exitChan chan bool
}

Workerを定義。Tickerによる通知のタイミングで走らせたい処理を書く。
監視ならCPUの使用率とかそんなの。

// Define the worker to monitoring by ticker.
func (mt MonTick) work() {

    go func() {
    forLoop:
        for {
            select {
            case <-mt.Tick.C:
                log.Print(mt.text + ": I'm working !")
            case <-mt.exitChan:
                break forLoop
            }
        }
        log.Print("Exited: " + mt.text)
    }()
}

Functionは適当に用意。
エラー処理とかもうちょっとしたほうがいいんだろうけどよくわからない。。。
CreateもExitも「OK」とか言いながらエラーハンドリング全くしてないやつ(


// Create workers.
func createWorkers() (mtArray []MonTick) {
    log.Print("Creating Monitors... ")

    for i := 0; i < 100; i++ {
        time.Sleep(time.Millisecond * 1)
        rand.Seed(time.Now().UnixNano())
        sec := rand.Intn(60) + 1
        ssec := "job-" + strconv.Itoa(sec)
        log.Print("    Created: ", ssec)
        mtArray = append(mtArray, createMonTick(sec, ssec))
    }
    log.Print("Created Monitors... [ OK ]")

    return
}

// Create ticker struct.
func createMonTick(sec int, str string) (mt MonTick) {
    tick := time.NewTicker(time.Second * time.Duration(sec))
    mt = MonTick{tick, sec, str, make(chan bool)}

    return
}

// Run all workers.
func runAllTickers(mtArray []MonTick) {
    log.Print("Running All Monitors... ")
    for _, v := range mtArray {
        v.work()
    }
    log.Print("[ OK ]")
}
func exitAllTickers(mtArray []MonTick) {
    log.Print("Exiting All Monitors... ")
    for _, v := range mtArray {
        v.exitChan <- true
    }
}

あとはmainでぐるぐる。
ランダム秒ごとに「おれしごとしてるぜ!!」アピールをし続けるWorkerたちを、60秒後にみんな停止させて終了。

// Main function.
func main() {

    mtArray := createTickers()
    runAllTickers(mtArray)

    for {
        time.Sleep(time.Second * 60)
        break
    }
    exitAllTickers(mtArray)
    time.Sleep(time.Second * 5)
    log.Print("Exit the application. ")

}

おわりに

今は単一処理なのでもう2・3処理を作って指定したFunctionを動かすような感じにしたい。
あとは外部からの読み込みかなー。

5
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
7