分享
  1. 首页
  2. 文章

golang--使用channel来同步goroutine

getong · · 4951 次点击 · · 开始浏览
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

在golang中同步goroutine有2种方法,要么使用channel,要么使用sync.WaitGroup,本文就是介绍如何通过channel来同步goroutine。先看代码。

 1 package main
 2 
 3 import (
 4 "os"
 5 "os/signal"
 6 "runtime"
 7 "log"
 8 "syscall"
 9 )
10 
11 const NUM_OF_QUIT int = 100
12 
13 func main() {
14  runtime.GOMAXPROCS(runtime.NumCPU())
15 done := make(chan bool)
16 receive_channel := make(chan chan bool)
17 finish := make(chan bool)
18 
19 
20 for i := 0; i < NUM_OF_QUIT; i++ {
21  go do_while_select(i, receive_channel, finish)
22  }
23 
24  go handle_exit(done, receive_channel, finish)
25 
26 <-done
27 os.Exit(0)
28 
29 }
30 func handle_exit(done chan bool, receive_channel chan chan bool, finish chan bool) {
31 sigs := make(chan os.Signal, 1)
32  signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)
33 chan_slice := make([]chan bool, 0)
34 for {
35 select {
36 case <-sigs:
37 for _, v := range chan_slice {
38 v <- true
39  }
40 for i := 0; i < len(chan_slice); i++ {
41 <-finish
42  }
43 done <- true
44  runtime.Goexit()
45 case single_chan := <-receive_channel:
46 log.Println("the single_chan is ", single_chan)
47 chan_slice = append(chan_slice, single_chan)
48  }
49  }
50 }
51 func do_while_select(num int, rece chan chan bool, done chan bool) {
52 quit := make(chan bool)
53 rece <- quit
54 for {
55 select {
56 case <-quit:
57 done <- true
58  runtime.Goexit()
59 default:
60 //简单输出
61 log.Println("the ", num, "is running")
62  }
63  }
64 }

上面的代码保存为example.go,通过gotool编译代码:

go build example.go

在当前目录下有example文件,在终端运行这个文件

2013/03/19 21:17:14 the 0 is running
2013/03/19 21:17:14 the 0 is running
2013/03/19 21:17:14 the 0 is running
2013/03/19 21:17:14 the 0 is running
2013/03/19 21:17:14 the 0 is running
2013/03/19 21:17:14 the 0 is running
2013/03/19 21:17:14 the 0 is running
2013/03/19 21:17:14 the 0 is running
2013/03/19 21:17:14 the 0 is running
2013/03/19 21:17:14 the 0 is running
2013/03/19 21:17:14 the 0 is running
2013/03/19 21:17:14 the 0 is running
2013/03/19 21:17:14 the 0 is running
2013/03/19 21:17:14 the 0 is running
......

上面不断输出goroutine中的数字,等待退出信号。

新打开一个终端,通过ps找到这个进程名,通过kill工具干掉这个进程:

$ps aux | grep example
user 4026 77.9 0.0 39436 1716 pts/1 Sl+ 21:19 0:17 ./example
$kill 4026

不久就可以看到在第一个终端里面不再打印,至此演示完毕。

代码思想:

新建NUM_OF_QUIT个goroutine,这些个goroutine里面新建1个chan bool,通过这个channel来接受退出的信号,这些channel在新建的时候,已经发给了handle_exit。在handle_exit这个goroutine里面,1方面监控由系统发过来的退出信号,然后再通知其他的goroutin优雅地退出;另一方面通过slice收集其他goroutine发过来的channel。handle_exit通知其他的goroutine优雅退出后,再发信号给main进程主动退出。

可以修改NUM_OF_QUIT值,例如改为10000,这个时候,kill命令发出去后,要等待相当长的一段时间才能看到第一个终端停止打印。

参考:

Go by Example: Signals

https://gobyexample.com/signals

转贴请注明来自:格通


有疑问加站长微信联系(非本文作者)

本文来自:博客园

感谢作者:getong

查看原文:golang--使用channel来同步goroutine

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

关注微信
4951 次点击
暂无回复
添加一条新回复 (您需要 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传

用户登录

没有账号?注册
(追記) (追記ここまで)

今日阅读排行

    加载中
(追記) (追記ここまで)

一周阅读排行

    加载中

关注我

  • 扫码关注领全套学习资料 关注微信公众号
  • 加入 QQ 群:
    • 192706294(已满)
    • 731990104(已满)
    • 798786647(已满)
    • 729884609(已满)
    • 977810755(已满)
    • 815126783(已满)
    • 812540095(已满)
    • 1006366459(已满)
    • 692541889

  • 关注微信公众号
  • 加入微信群:liuxiaoyan-s,备注入群
  • 也欢迎加入知识星球 Go粉丝们(免费)

给该专栏投稿 写篇新文章

每篇文章有总共有 5 次投稿机会

收入到我管理的专栏 新建专栏