任务数量为50,并发在5,全部都要执行
Go
package main
import (
"fmt"
"time"
)
type Con struct {
num int
time string
}
func main() {
//channel实现并发控制
// 定义同时执行的任务数量
concurrencyLevel := 5
//总任务数
totalTask := 50
// 创建一个有缓冲的 channel 用于控制并发数
taskChan := make(chan int, concurrencyLevel)
// 创建一个 channel 用于标记所有任务完成
doneChan := make(chan *Con, totalTask)
// 启动指定数量的 goroutine 来并发执行任务
for i := 0; i < concurrencyLevel; i++ {
go concurrentTask(taskChan, doneChan)
}
// 发送任务到 taskChan
//循环发送任务,保证每个任务都能发送到,如果发送任务时 taskChan 阻塞,等待一段时间再重试
for i := 1; i <= totalTask; i++ {
select {
// 发送任务到 taskChan
case taskChan <- i:
//fmt.Printf("任务 %d 已发送\n", i)
default:
fmt.Println("任务发送阻塞,等待空闲...", i)
// 等待 1 秒钟再重试
time.Sleep(1 * time.Second)
i--
}
}
// 关闭 taskChan,通知所有的 goroutine 没有更多的任务
close(taskChan)
// 关闭 doneChan
close(doneChan)
等待所有任务完成,并关闭 doneChan
for res := range doneChan {
fmt.Printf("任务 %d 完成, 完成时间:%s\n", res.num, res.time)
}
fmt.Println("所有任务已完成")
}
// 模拟一个并发执行的任务
func concurrentTask(taskChan chan int, doneChan chan *Con) {
defer func() {
// 捕获 panic,recover() 函数可以让程序从 panic 中恢复
if r := recover(); r != nil {
fmt.Println("任务发生panic,正在恢复:", r)
}
}()
// 从 taskChan 中获取任务
for task := range taskChan {
fmt.Printf("处理任务 %d\n", task)
time.Sleep(1 * time.Second) // 模拟任务执行时间
//任务执行完毕,将任务结果发送到 doneChan
doneChan <- &Con{num: task, time: time.Now().Format("2006-01-02 15:04:05")}
}
}
任务数量为50,并发在5,遇到阻塞的就不再执行
Go
package main
import (
"fmt"
"time"
)
type Con struct {
num int
time string
}
func main() {
//channel实现并发控制
// 定义同时执行的任务数量
concurrencyLevel := 5
//总任务数
totalTask := 50
// 创建一个有缓冲的 channel 用于控制并发数
taskChan := make(chan int, concurrencyLevel)
// 创建一个 channel 用于标记所有任务完成
doneChan := make(chan *Con, totalTask)
// 启动指定数量的 goroutine 来并发执行任务
for i := 0; i < concurrencyLevel; i++ {
go concurrentTask(taskChan, doneChan)
}
// 发送任务到 taskChan
//循环发送任务,保证每个任务都能发送到,如果发送任务时 taskChan 阻塞,等待一段时间再重试
for i := 1; i <= totalTask; i++ {
select {
// 发送任务到 taskChan
case taskChan <- i:
//fmt.Printf("任务 %d 已发送\n", i)
default:
fmt.Println("任务发送阻塞,等待空闲...", i)
}
}
// 关闭 taskChan,通知所有的 goroutine 没有更多的任务
close(taskChan)
// 关闭 doneChan
close(doneChan)
等待所有任务完成,并关闭 doneChan
for res := range doneChan {
fmt.Printf("任务 %d 完成, 完成时间:%s\n", res.num, res.time)
}
fmt.Println("所有任务已完成")
}
// 模拟一个并发执行的任务
func concurrentTask(taskChan chan int, doneChan chan *Con) {
defer func() {
// 捕获 panic,recover() 函数可以让程序从 panic 中恢复
if r := recover(); r != nil {
fmt.Println("任务发生panic,正在恢复:", r)
}
}()
// 从 taskChan 中获取任务
for task := range taskChan {
fmt.Printf("处理任务 %d\n", task)
time.Sleep(1 * time.Second) // 模拟任务执行时间
//任务执行完毕,将任务结果发送到 doneChan
doneChan <- &Con{num: task, time: time.Now().Format("2006-01-02 15:04:05")}
}
}