go cluster note
1, 占位
type func interface 范式
type myFunc func(int) int func (f myFunc) sum (a, b int) int { res := a + b return f(res) } func sum10(num int) int { return num * 10 } func sum100(num int) int { return num * 100 } func handlerSum(handler myFunc, a, b int) int { res := handler.sum(a, b) fmt.Println(res) return res } func main() { newFunc1 := myFunc(sum10) newFunc2 := myFunc(sum100) handlerSum(newFunc1, 1, 1) // 20 handlerSum(newFunc2, 1, 1) // 200 }
from https://www.cnblogs.com/tr3e/p/7995689.html
1,占位
func HeavyWork(id int) { rand.Seed(int64(id)) interval := time.Duration(rand.Intn(3)+1) * time.Second time.Sleep(interval) fmt.Printf("HeavyWork %-3d cost %v\n", id, interval) }
2,每个任务完成后向waitChan写入一个数据,在收到N个完成信号后退出
// "talk is cheap, show me the code." func main() { waitChan := make(chan int, 1) for i := 0; i < N; i++ { go func(n int) { HeavyWork(n) waitChan <- 1 }(i) } cnt := 0 for range waitChan { //是用for 读取chan,如果不读取, go func 会阻塞, 主程序for 结束时,也就是并发结束时 cnt++ if cnt == N { break } } close(waitChan) fmt.Println("finished") }
和这一段等效
// "talk is cheap, show me the code."
// Add 用来添加 goroutine 的个数。Done 执行一次数量减 1。Wait 用来等待结束 func main() { wg := sync.WaitGroup{} for i := 0; i < N; i++ { wg.Add(1) go func(n int) { defer wg.Done() HeavyWork(n) }(i) } wg.Wait() fmt.Println("finished") }
##########################################
超时机制
1, 超时
func main() { ok, quit := make(chan int, 1), make(chan int, 1) go func() { i := 0 for { select { case <- quit: //如果quit成功读到数据,则进行该case处理语句,如果不给 quit 传值,则不执行 ok <- 1 //给chan ok 传值,如果没有读ok,则阻塞 return default: HeavyWork(i) i++ } } }() time.Sleep(5 * time.Second) quit <- 1 //不给quit值,会 <-ok }
#############
入门坑路标
https://www.cnblogs.com/jhhe66/articles/9232691.html
############
主进程杀掉超时进程
https://www.cnblogs.com/sunlong88/p/12202257.html
func main() { var ( cmd *exec.Cmd //output []byte //err error ) ctx, cancelFunc := context.WithCancel(context.Background()) go func() { // 生成Cmd cmd = exec.CommandContext(ctx, "/bin/bash", "-c", "python -m SimpleHTTPServer 80") cmd.SysProcAttr = &syscall.SysProcAttr{} var b bytes.Buffer cmd.Stdout = &b //剧透,坑在这里 cmd.Stderr = &b if err := cmd.Start(); err != nil { fmt.Println(err) return } // 超时杀掉进程组 或正常退出 go func() { select { case <-ctx.Done(): //收到结束信号,打印id fmt.Println( cmd.Process.Pid) } }() if err := cmd.Wait(); err != nil { fmt.Println(err) fmt.Println("recive: ", b.String()) return } fmt.Println("recive: ", b.String()) }() time.Sleep(time.Second*20) cancelFunc() //这里是cancel 操作 fmt.Println(9999999) // 打印子进程的输出 time.Sleep(time.Second*1000) }