概述
一、使用channel来等待goroutine结束
方法一:
type worker struct {
in chan int
done chan bool
}
func doneWorker(id int, w worker) {
for n := range w.in {
fmt.Printf("worker %d received %cn", id, n)
w.done <- true
}
}
func createWorker(id int) worker{
w := worker{
in: make(chan int),
done: make(chan bool),
}
go doneWorker(id, w)
return w
}
func chanDemo() {
var workers [10]worker
for i, _ := range workers {
workers[i] = createWorker(i)
}
for i, worker := range workers {
worker.in <- 'a' + i
}
for _, worker := range workers{
<- worker.done
}
for i, worker := range workers {
worker.in <- 'A' + i
}
for _, worker := range workers{
<- worker.done
}
}
func main() {
chanDemo()
}
方法二:
type worker struct {
in chan int
done func()
}
func doneWorker(id int, w worker) {
for n := range w.in {
fmt.Printf("worker %d received %cn", id, n)
w.done()
}
}
func createWorker(id int, wg *sync.WaitGroup) worker{
w := worker{
in: make(chan int),
done: func() {
wg.Done()
},
}
go doneWorker(id, w)
return w
}
func chanDemo() {
var wg sync.WaitGroup
var workers [10]worker
for i, _ := range workers {
workers[i] = createWorker(i, &wg)
}
wg.Add(20)
for i, worker := range workers {
worker.in <- 'a' + i
}
for i, worker := range workers {
worker.in <- 'A' + i
}
wg.Wait()
}
func main() {
chanDemo()
}
二、使用Channel来实现树的遍历
func (node *Node) TraverseWithChannel() chan *Node{
out := make(chan *Node)
go func() {
node.TraverseFunc(func(node *Node) {
out <- node
})
close(out)
}()
return out
}
三、使用Select来进行调度
1.定时器的使用
2.select中使用Nil channel
3.select default(非阻塞式从channel中获取值)
func generator() chan int{
out := make(chan int)
go func() {
i := 0
for {
time.Sleep(time.Duration(rand.Intn(1500)) * time.Millisecond)
out <- i
i++
}
}()
return out
}
func worker(id int, c chan int) {
for n := range c {
time.Sleep(1 * time.Second)
fmt.Printf("Worker %d received %dn", id, n)
}
}
func createWorker(id int) chan int{
c := make(chan int)
go worker(id, c)
return c
}
func main() {
var c1, c2 = generator(), generator() // c1 and c2 = nil
w := createWorker(0)
var values []int
tm := time.After(10 * time.Second)
tick := time.Tick(time.Second)
for {
var activeWorker chan int
var activerValue int
if len(values) > 0 {
activeWorker = w
activerValue = values[0]
}
select {
case n := <-c1:
values = append(values, n)
case n := <-c2:
values = append(values, n)
case activeWorker <-activerValue:
values = values[1:]
case <-time.After(800 * time.Millisecond):
fmt.Println("timeout")
case <-tick:
fmt.Println("queue len =", len(values))
case <-tm:
fmt.Println("Bye")
return
//default:
//fmt.Println("No value received")
}
}
}
四、传统同步机制
1.WaitGroup
2.Mutex
3.Cond
type atomicInt struct {
value int
lock sync.Mutex
}
func (a *atomicInt) increment(){
fmt.Println("safe increment")
func(){
a.lock.Lock()
defer a.lock.Unlock()
a.value++
}()
}
func (a *atomicInt) get() int {
a.lock.Lock()
defer a.lock.Unlock()
return a.value
}
func main() {
var a atomicInt
a.increment()
go func() {
a.increment()
}()
time.Sleep(time.Millisecond)
fmt.Println(a.get())
}
最后
以上就是英俊香菇为你收集整理的Go语言使用channel等待任务结束的全部内容,希望文章能够帮你解决Go语言使用channel等待任务结束所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复