golang实现协程池

golang中启动一个协程不会消耗太多资源,有人认为可以不用协程池。但是当访问量增大时,可能造成内存消耗完,程序崩溃。于是写了一个协程池的Demo。 Demo中有worker和job。worker是一个协程,在worker中完成一个job。Jobs是一个channel,使用Jobs记录job。当生成一个新任务,就发送到Jobs中。程序启动时,首先启动3个worker协程,每个协程都尝试从Jobs中接收job。如果Jobs中没有job,worker协程就等待。 基本逻辑如下:

Jobs管道存放job,Results管道存放结果。 程序一启动,启动3个worker协程,等待从Jobs管道中取数据。 向Jobs管道中发送3个数据。 关闭Jobs管道。 worker协程从Jobs管道中接收到数据以后,执行程序,把结果放到Results管道中。然后继续等待。 当Jobs管道中没有数据,并且Results有3个数据时。退出主程序。

代码如下:

package main

import (
    "fmt"
    "time"
)

type Job struct {
    JobId int
}

func worker(id int) {
    go func() {
        for {
            fmt.Println("Waiting for job...")
            select {
            // Receive from channel
            case j := <-Jobs :
                if j == nil {
                    fmt.Println("Close the worker", id)
                    return
                }
                fmt.Println("worker", id, "started  job", j.JobId)
                time.Sleep(time.Second)
                fmt.Println("worker", id, "finished job", j.JobId)
                Results <- true
            }
        }
    }()
}

const channelLength = 3

var (
    Jobs chan *Job
    Results chan bool
)

func main() {
    Jobs = make(chan *Job, channelLength)
    Results = make(chan bool, channelLength)

    // Start worker goroutines
    for i:= 0; i < channelLength; i++ {
        worker(i)
    }

    // Send to channel
    time.Sleep(time.Second)
    for j := 0; j < channelLength; j++ {
        Jobs <- &Job{JobId:j}
    }
    close(Jobs)

    for len(Jobs) != 0 || len(Results) != channelLength  {
        time.Sleep(100 * time.Millisecond)
    }
    fmt.Println("Complete main")
}

转载于:https://my.oschina.net/Alexmyj/blog/3000477

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值