golang/goroutine 和 swoole/coroutine 协程性能测试对比 - Go语言中文网 - Golang中文社区 https://studygolang.com/articles/13967#reply0

Go 语言之旅 https://tour.go-zh.org/concurrency/1

协程的一些特性和优点我就不说了,网上很多文章都讲述的很透彻。

协程可以理解为纯用户态的线程,其通过协作而不是抢占来进行切换。相对于进程或者线程,协程所有的操作都可以在用户态完成,创建和切换的消耗更低。开发者可以无感知的用同步的代码编写方式达到异步IO的效果和性能,避免了传统异步回调所带来的离散的代码逻辑和陷入多层回调中导致代码无法维护。

1、golang::goroutine

最近在学习 go,一些高大上的特性果然是为高并发而生,自带的 net/http 包对请求的处理也透明的放在了协程上下文中,真开箱即用。

server.go

package main

import (
"fmt"
"net/http"
"time"
"log"
"runtime"
"bytes"
"strconv"
) func main() {
// 注册请求 handler
http.HandleFunc("/", func (responseWrite http.ResponseWriter, request *http.Request) {
log.Println("goroutine: ", GetGID(), "start")
// 模拟2秒的IO耗时操作 会发生协程切换
time.Sleep(2 * time.second)
// 协程继续执行
log.Println("goroutine: ", GetGID(), "end")
// 结束请求
fmt.Fprintln(responseWrite, "<h1>hello world!</h1>")
}) log.Println("server start ...") http.ListenAndServe(":8081", nil)
} // 获取 goroutine 的协程 id
func GetGID() uint64 {
b := make([]byte, 64)
b = b[:runtime.Stack(b, false)]
b = bytes.TrimPrefix(b, []byte("goroutine "))
b = b[:bytes.IndexByte(b, ' ')]
n, _ := strconv.ParseUint(string(b), 10, 64)
return n
}

golang 自带的 net/http 包是会自行的创建一个协程去处理请求的,所以阻塞的 2秒 并不会将主进程挂起,主进程仍在不停的接收请求并创建一个协程去处理请求。

Go 程(goroutine)是由 Go 运行时管理的轻量级线程。

go f(x, y, z)

会启动一个新的 Go 程并执行

f(x, y, z)

f, x, y 和 z 的求值发生在当前的 Go 程中,而 f 的执行发生在新的 Go 程中。

Go 程在相同的地址空间中运行,因此在访问共享的内存时必须进行同步。sync包提供了这种能力,不过在 Go 中并不经常用到,因为还有其它的办法(见下一页)。

信道

信道是带有类型的管道,你可以通过它用信道操作符 <- 来发送或者接收值。

ch <- v    // 将 v 发送至信道 ch。
v := <-ch // 从 ch 接收值并赋予 v。

(“箭头”就是数据流的方向。)

和映射与切片一样,信道在使用前必须创建:

ch := make(chan int)

默认情况下,发送和接收操作在另一端准备好之前都会阻塞。这使得 Go 程可以在没有显式的锁或竞态变量的情况下进行同步。

以下示例对切片中的数进行求和,将任务分配给两个 Go 程。一旦两个 Go 程完成了它们的计算,它就能算出最终的结果。

package main

import "fmt"

func sum(s []int, c chan int) {
sum := 0
for _, v := range s {
sum += v
}
c <- sum // 将和送入 c
}

func main() {
s := []int{7, 2, 8, -9, 4, 0}

c := make(chan int)
go sum(s[:len(s)/2], c)
go sum(s[len(s)/2:], c)
x, y := <-c, <-c // 从 c 中接收

fmt.Println(x, y, x+y)
}

无感知的用同步的代码编写方式达到异步IO的效果和性能,避免了传统异步回调所带来的离散的代码逻辑和陷入多层回调中导致代码无法维护的更多相关文章

  1. 代码编写规范说明书(c#.net与asp.net)

    代码编写规范说明书(c#.net与asp.net) 目 录1 目的2 范围3 注释规范3.1 概述3.2 自建代码文件注释3.3 模块(类)注释3.4 类属性注释3.5 方法注释3.6 代码间注释4 ...

  2. 最新的JavaScript核心语言标准——ES6,彻底改变你编写JS代码的方式!【转载+整理】

    原文地址 本文内容 ECMAScript 发生了什么变化? 新标准 版本号6 兑现承诺 迭代器和for-of循环 生成器 Generators 模板字符串 不定参数和默认参数 解构 Destructu ...

  3. Java代码编写的一般性指导

    (1) 命名规则:这个最基本,也最重要,请牢记. 1,类名首字母应该大写. 2,字段.方法以及对象(句柄)的首字母应小写. 3,对于所有标识符,其中包含的所有单词都应紧靠在一起,而且大写中间单词的首字 ...

  4. Java代码编写的30条建议

    1) 类名首字母应该大写.字段.方法以及对象(句柄)的首字母应小写.对于所有标识符,其中包含的所有单词都应紧靠在一起,而且大写中间单词的首字母.例如: ThisIsAClassName thisIsM ...

  5. 14条最佳JS代码编写技巧

    http://gaohaixian.blog.163.com/blog/static/123260105201142645458315/写任何编程代码,不同的开发者都会有不同的见解.但参考一下总是好的 ...

  6. NASA的10条代码编写原则

    NASA的10条代码编写原则 作者: Gerard J. Holzmann 来源: InfoQ 原文链接 英文原文:NASA's 10 Coding Rules for Writing Safety ...

  7. 最新的JavaScript核心语言标准——ES6,彻底改变你编写JS代码的方式!

    原文地址 迁移到:http://www.bdata-cap.com/newsinfo/1741515.html 本文内容 ECMAScript 发生了什么变化? 新标准 版本号6 兑现承诺 迭代器和f ...

  8. 为代码编写稳定的单元测试 [Go]

    为代码编写稳定的单元测试 本文档配套代码仓库地址: https://github.com/liweiforeveryoung/curd_demo 配合 git checkout 出指定 commit ...

  9. .NET代码编写规范 整理

    .NET代码编写规范 整理 .NET代码编写规范 - [ASP.NET] 2009-02-26 | Tag: 版权声明:转载时请以超链接形式标明文章原始出处和作者信息及本声明 http://lensp ...

随机推荐

  1. linux 程序自动运行总结

    1.开机启动时自动运行程序Linux加载后, 它将初始化硬件和设备驱动, 然后运行第一个进程init.init根据配置文件继续引导过程,启动其它进程.通常情况下,修改放置在 /etc/rc或 /etc ...

  2. php解析json字符串变量总是空白null

    通过接口获取的json字符串使用json_decode始终无法正确解析,返回空白. 直接把结果字符串复制出来手动创建一个变量却正常,在前端js也能解析,搞了半天不得其解,最后发现是接口输出的结果包含有 ...

  3. CocoaPods | iOS详细使用说明

    一:介绍 在iOS开发中,经常会使用到第三方库,[CocoaPods](https://github.com/CocoaPods/CocoaPods)可以用来方便的统一管理这些第三方库. 下面就和大家 ...

  4. 2016-2017 ACM-ICPC, South Pacific Regional Contest (SPPC 16)

    题目链接  Codeforces_Gym_101177 Problem A  Anticlockwise Motion 直接模拟即可 #include<iostream> #include ...

  5. HTTP/1.1标准请求方法和状态码

    HTTP/1.1标准自从1999年制定以来至今仍然是一个应用广泛并且通行的标准 相关文档 RFC2616:Hypertext Transfer Protocol -- HTTP/1.1 在RFC658 ...

  6. git 撤回上一次commit中某一个不想添加的文件

    1. 假设我们修改了文件a,同时修改了IDE的配置文件b 2.此时我们只想添加文件a到commit中,却不小心将b也添加进去了 3.那么怎么撤回呢? 4.第一种方法 :重新提交commit 5. 第二 ...

  7. BZOJ 2131 [scoi2010] 传送带

    @(BZOJ)[三分法] Description 在一个2维平面上有两条传送带,每一条传送带可以看成是一条线段. 两条传送带分别为线段AB和线段CD. lxhgww在AB上的移动速度为P,在CD上的移 ...

  8. lua——基础语法

    -- test lua: for learning lua grammar -- line comment --[[ block comment ]]-- -- print hello world p ...

  9. spring secrity 一些常用小知识

    1.在JSP页面获取当前登录的用户名的方法 首先引入taglib:<%@ taglib prefix="sec" uri="http://www.springfra ...

  10. yarn 基本用法

    1.初始化一个新的项目 yarn init 2.添加一个依赖包 yarn add [package] yarn add [package]@[version] yarn add [package]@[ ...