golang并发以及任务控制

golang 并发

并发模式实例

例子
消息生成器

模拟消息生成接收

package main

import (
	"fmt"
	"math/rand"
	"time"
)

// 模拟两秒内产生数据
func msgGen(name string) chan string {
	c := make(chan string)
	go func() {
		i := 0
		for {
			time.Sleep(time.Duration(rand.Intn(2000)) * time.Millisecond)
			c <- fmt.Sprintf("service %s: message %d", name, i)
			i++
		}
	}()
	return c
}
// 同时等待多个服务
/*
拿一个管道汇总多个管道的数据
*/
func fanIn(chs ...chan string) chan string {
	c := make(chan string)
	for _, ch := range chs {
		go func(in chan string) {
			for {
				c <- <-in
			}
		}(ch)
	}
	return c
}
/*
select 版
*/
func fanInBySelect(c1, c2 chan string) chan string {
	c := make(chan string)
	go func() {
		for {
			select {
			case m := <-c1:
				c <- m
			case m := <-c2:
				c <- m
			}
		}
	}()
	return c
}

func main() {
	m1 := msgGen("service1")
	m2 := msgGen("service2")
	m3 := msgGen("service3")
	m := fanIn(m1, m2, m3)
	for {
		fmt.Println(<-m)
	}
}

并发任务控制实例

通过上面的程序,模拟非阻塞、超时等、任务中断,优雅退出例子

package main

import (
	"fmt"
	"math/rand"
	"time"
)

func msgGen(name string, done chan struct{}) chan string {
	c := make(chan string)
	go func() {
		i := 0
		for {
			// 如果要中止任务,需要跳出来
			select {
			case <-time.After(time.Duration(rand.Intn(2000)) * time.Millisecond):
				c <- fmt.Sprintf("service %s: message %d", name, i)
			case <-done:
				fmt.Println("cleaning up")
				time.Sleep(time.Second * 2)  // 模拟两秒才清理完
				fmt.Println("cleaning done")
				done <- struct{}{}
				return
			}

			i++
		}
	}()
	return c
}
// 同时等待多个服务
/*
拿一个管道汇总多个管道的数据
*/
func fanIn(chs ...chan string) chan string {
	c := make(chan string)
	for _, ch := range chs {
		go func(in chan string) {
			for {
				c <- <-in
			}
		}(ch)
	}
	return c
}
/*
select 版
*/
func fanInBySelect(c1, c2 chan string) chan string {
	c := make(chan string)
	go func() {
		for {
			select {
			case m := <-c1:
				c <- m
			case m := <-c2:
				c <- m
			}
		}
	}()
	return c
}

// 任务控制
// 非阻塞等待
func nonBlockingWait (c chan string) (string, bool) {
	select {
	case m := <- c:
		return m, true
	default:
		return "", false
	}
}

func timeoutWait(c chan string, timeout time.Duration) (string, bool) {
	select {
	case m := <- c:
		return m, true
	case <-time.After(timeout):
		return "", false
	}
}
func main() {
	done := make(chan struct{})
	m1 := msgGen("service1", done)
	m2 := msgGen("service2", done)
	m3 := msgGen("service3", done)
	m := fanIn(m1, m2, m3)

	for i := 0; i < 5; i++{
		fmt.Println(<-m)
		if m , ok := timeoutWait(m2, time.Second); ok {
			fmt.Println(m)
		} else {
			fmt.Println("no message from svc2")
		}
	}

	done <- struct{}{}
	time.Sleep(time.Second)
	// 模拟服务器优雅推出
	<- done
	fmt.Println("server exit")
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值