Go并发(1)

Go从语言本身支持并发,而不是由某个库或者模块来实现并发,可谓天生丽质。goroutine从根本上与线程不同,goroutine更加轻量化。   看下面这个常见的网络模型:package mainimport ( "fmt" "net")func manageClient(conn net.Conn) { conn.Write([]byte("Hi!")) conn.Close(
摘要由CSDN通过智能技术生成

  Go从语言本身支持并发,而不是由某个库或者模块来实现并发,可谓天生丽质。goroutine从根本上与线程不同,goroutine更加轻量化。
  看下面这个常见的网络模型:

package main

import (
  "fmt"
  "net"
)

func manageClient(conn net.Conn) {
  conn.Write([]byte("Hi!"))
  conn.Close()
  //do something with the client
}

func main() {
  //we are creating a server her that listenson port 1337. 
  listener, err := net.Listen("tcp", ":1337")
  for {
    //accept a connection
    connection, _ := listener.Accept()
    go manageClient(connection)
  }
}

  在main函数调用net.Listen方法进行监听,该方法会返回两个值,一个是服务器连接,另一个是错误数据。然后,进入到服务的主循环部分,程序调用server.Accept方法,然后等待请求。该方法调用后,程序会被挂起,直到有有一个客户端的连接出现。一旦有个连接出现,我们将connection对象传值到manageClient方法中,由于通过goroutine的方式调用manageClient,所以主程序会继续等待处理下一个客户端连接请求。

  上面的代码清晰明了,Go允许使用go语句开启一个新的运行期线程,即 goroutine,以一个不同的、新创建的goroutine来执行一个函数。同一个程序中的所有goroutine共享同一个地址空间。
  Goroutine非常轻量,除了为之分配的栈空间,其所占用的内存空间微乎其微。并且其栈空间在开始时非常小,之后随着堆存储空间的按需分配或释放而变化。内部实现上,goroutine会在多个操作系统线程上多路复用。如果一个goroutine阻塞了一个操作系统线程,例如:等待输入,这个线程上的其他goroutine就会迁移到其他线程,这样能继续运行。

  让我们接着来看下面这个例子:

package main

import (
  "fmt"
)

func sayHello() {
  fmt.Println("Hello, world!")
}

func main() {
  //run a goroutine that says hello
  go sayHello()
}

  上述程序会输出什么?什么也不会输出,因为sayHello这个goroutine还没来得及跑,主函数已经退出了。
  在C++/Java/Python里面,都有类似Join的东东来等待子线程,而go里面是用Channels来实现的,Channels是一种goroutine之间或者goroutine和主进程之间的通信机制。

  把上述程序改为:

package main

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

One2zeror

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值