|
|
51CTO旗下网站
|
|
移动端

10.1.2 指定使用核心数

《Go语言编程入门与实战技巧》第10章并发编程,本章Go语言里的并发指的是能让某个函数独立于其他函数运行的能力。当一个函数创建为协程(goroutine)时,Go语言会将其视为一个独立的工作单元,这个单元会被调度到可用的逻辑处理器上执行。本节为大家介绍指定使用核心数。

作者:黄靖钧来源:电子工业出版社|2018-09-23 09:43

10.1.2  指定使用核心数

Go语言默认会调用CPU核心数,这些功能都是自动调整的,但是也提供了相应的标准库来指定核心数。使用flags包可以调整程序运行时调用的CPU核心数,如下:

  1. var numCores = flag.Int("n", 2, "CPU核心数")  
  2.  
  3. in main()  
  4. flag.Pars()  
  5. runtime.GOMAXPROCS(*numCores)  

协程可以通过调用runtime.Goexit()来停止,尽管这样做几乎没有必要:

  1. // 示例代码10-1  
  2. package main  
  3.  
  4. import (  
  5.     "fmt"  
  6.     "time"  
  7. )  
  8.  
  9. func main() {  
  10.     fmt.Println("这里是main()开始的地方")  
  11.     go longWait()  
  12.     go shortWait()  
  13.     fmt.Println("挂起main()")  
  14.     // 挂起工作时间以纳秒(ns)为单位  
  15.     time.Sleep(10 * 1e9)  
  16.     fmt.Println("这里是main()结束的地方")  
  17. }  
  18.  
  19. func longWait() {  
  20.     fmt.Println("开始longWait()")  
  21.     time.Sleep(5 * 1e9) // 等待5秒  
  22.     fmt.Println("结束longWait()")  
  23. }  
  24.  
  25. func shortWait() {  
  26.     fmt.Println("开始shortWait()")  
  27.     time.Sleep(2 * 1e9) // 等待2秒  
  28.     fmt.Println("结束shortWait()")  
  29. }  
  30. /*  
  31. 返回:  
  32. 这里是main()开始的地方  
  33. 挂起main()  
  34. 开始longWait()  
  35. 开始shortWait()  
  36. 结束shortWait()  
  37. 结束longWait()  
  38. 这里是main()结束的地方 // 过了10秒  
  39. */  

main()、longWait()和shortWait()三个函数作为独立的处理单元按顺序启动,然后开始并行运行,每一个函数都在运行的开始和结束阶段输出了消息。为了模拟它们运算的时间消耗,使用了time包中的Sleep函数。Sleep()可以按照指定的时间来暂停函数或协程的执行,这里使用了纳秒(ns,符号1e9表示1乘以10的9次方,e=指数)。

它们按照我们期望的顺序打印出了消息,几乎都一样,可是我们明白这是模拟出来的,并且是并行的方式。让main()函数暂停10秒从而确定它会在另外两个协程之后结束。如果不这样(如果让main()函数停止4秒),main()会提前结束,longWait()则无法完成。如果不在main()中等待,协程会随着程序的结束而消亡。

当main()函数返回的时候,程序退出:它不会等待任何其他非main协程的结束。这就是为什么在服务器程序中,每一个请求都会启动一个协程来处理,server()函数必须保持运行状态。通常使用一个无限循环来达到这样的目的。

另外,协程是独立的处理单元,一旦陆续启动一些协程,你无法确定它们是什么时候真正开始执行的。代码逻辑必须独立于协程调用的顺序。

为了对比使用一个线程连续调用的情况,移除Go语言关键字,重新运行程序:

  1. /*  
  2. 返回:  
  3. 这里是main()开始的地方  
  4. 开始longWait()  
  5. 结束longWait()  
  6. 开始shortWait()  
  7. 结束shortWait()  
  8. 挂起main()  
  9. 这里是main()结束的地方 // 过了17秒之后打印  
  10. */  

协程更有用的一个例子应该是在一个非常长的数组中查找一个元素。将数组分割为若干个不重复的切片,然后给每一个切片启动一个协程进行查找计算。这样许多并行的线程可以用于查找任务,整体的查找时间会缩短(除以协程的数量)。


喜欢的朋友可以添加我们的微信账号:

51CTO读书频道二维码


51CTO读书会第9群:808517103

【责任编辑:book TEL:(010)68476606】

回书目   上一节   下一节
点赞 0
分享:
大家都在看
猜你喜欢

读 书 +更多

网络管理员考试全真模拟试题与解析

本书是按照全国计算机技术与软件专业技术资格(水平)考试《网络管理员考试大纲》的要求,参照《网络管理员教程》及近年来考试试题编写的。...

订阅51CTO邮刊

点击这里查看样刊

订阅51CTO邮刊