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
", 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)
}