1、一个任务结束后,才执行下一个任务
type channell struct {
in chan int
done chan bool
}
func workGo(id int,c chan int,done chan bool) {
for a := range c{
fmt.Printf("work %d received %d\n",id,a)
done <- true
}
}
func work(id int) channell {
c := channell{ //通过通道共享内存
in: make(chan int),
done: make(chan bool),
}
go workGo(id,c.in,c.done)
return c
}
func chanMake(){
var channels [9]channell
for i:=0;i<9;i++ {
channels[i] = work(i)
}
for i:=0;i<9;i++ { //一共9个任务
channels[i].in <- i
<-channels[i].done //发一个任务等着这个任务结束,才执行下一个任务
}
}
func main(){
chanMake()
time.Sleep(time.Millisecond)
}
2、等待所有的任务都完成
type channell struct {
in chan int
done chan bool
}
func work(id int,c chan int,done chan bool) {
for a := range c{ //如果c放入数据之后, 没有显式关闭channel, 那么range会阻塞在该goroutine中.
fmt.Printf("channe %d received %d\n",id,a)
go func(){
done <- true
}()
}
}
func workGo(id int) channell {
c := channell{ //通过通道共享内存
in: make(chan int),
done: make(chan bool),
}
go work(id,c.in,c.done) //将通道(里面现在还没有数据)作为参数传进work中,但work里面真正需要的是通道里面的数据。
return c
}
func chanMake(){
var channels [9]channell
for i:=0;i<9;i++ {
channels[i] = workGo(i)
}
for i:=0;i<9;i++ {
channels[i].in <- i //现在c.in通道里有数据了,work里面需要数据的地方可以工作了,所以是通过通道共享内存,共享了i
}
for i:=0;i<9;i++ {
channels[i].in <- i + 'a'
}
for _,channell := range channels{ //等所有的任务都结束
<-channell.done
<-channell.done
}
}
func main(){
chanMake()
}
3、使用sync.WaitGroup等待所有任务完成
sync.WaitGroup只有3个方法,Add(),Done(),Wait()。其中Done()是Add(-1)的别名。简单的来说,使用Add()添加计数,Done()减掉一个计数,计数不为0, 阻塞Wait()的运行。
type channell struct {
in chan int
wg *sync.WaitGroup
}
func work(id int,c chan int,wg *sync.WaitGroup) {
for a := range c{ //如果c放入数据之后, 没有显式关闭channel, 那么range会阻塞在该goroutine中.
fmt.Printf("channe %d received %d\n",id,a)
wg.Done()
}
}
func workGo(id int,wg *sync.WaitGroup) channell {
c := channell{ //通过通道共享内存
in: make(chan int),
wg: wg,
}
go work(id,c.in,wg) //将通道(里面现在还没有数据)作为参数传进work中,但work里面真正需要的是通道里面的数据。
return c
}
func chanMake(){
var wg sync.WaitGroup
var channels [9]channell
for i:=0;i<9;i++ {
channels[i] = workGo(i,&wg)
}
wg.Add(18) //加进去18个任务
for i:=0;i<9;i++ {
channels[i].in <- i //现在c.in通道里有数据了,work里面需要数据的地方可以工作了,所以是通过通道共享内存,共享了i
}
for i:=0;i<9;i++ {
channels[i].in <- i + 'a'
}
wg.Wait() //等待这20个任务做完
}
func main(){
chanMake()
}
将wg.Done包装一下:
func work(id int,c channell) {
for a := range c.in{ //如果c放入数据之后, 没有显式关闭channel, 那么range会阻塞在该goroutine中.
fmt.Printf("channe %d received %d\n",id,a)
c.done()
}
}
func workGo(id int,wg *sync.WaitGroup) channell {
c := channell{ //通过通道共享内存
in: make(chan int),
done: func(){
wg.Done()
},
}
go work(id,c) //将通道(里面现在还没有数据)作为参数传进work中,但work里面真正需要的是通道里面的数据。
return c
}