golang

Golang: RobPike谈 并发Vs并行

≯℡__Kan透↙ 提交于 2019-12-01 21:55:30
很早的一个视频了, Rob Pike 演讲视频 《Concurrency Is Not Parallelism》。 Rob Pike 演讲 视频 : ‘Concurrency Is Not Parallelism’ — 一句话:并发更加复杂,更加优秀。(Go的并发可以利用多核&并行) Don’t communicate by shared memory. Instead, share memory by communicating. —— Rob Pike 很长的一段事件,我没有理解这句话。听了他的演讲,大致明白了: Goroutine 奉行通过通信来共享内存,而不是共享内存来通信。 因为 go 底层帮你封装了这些细 大专栏 Golang: RobPike谈 并发Vs并行 节(十几个goroutines 可能对应4-5个线程,整体上是一个大的线程池),使得你可以不必在关心这些细节。(你要合作 & 竞争,那么直接通过 chan 通信即可,通信的过程中,自动使用了共享内存,锁等等这些等机制) Go语言层面上也简化并发编程了难度,goroutines封装了原来需要同步,协作等线程问题。 你可以不必再关心线程,只用关心任务执行体,或者相应的工作即可 (实际上这么说恐怕不准确,因为多核执行的时候也有可能存在震荡,需要绑定线程) 进一步的深入探究,可以参考我的这篇文章: 《Golang:

初识golang

大兔子大兔子 提交于 2019-12-01 21:53:45
单例模式是设计模式里最为常用的一种,应用该设计模式的目的是保证类仅有一个全局的对象实例。 懒汉模式(Lazy Loading) 懒汉模式是最为简单常见的,最大的缺点是非线程安全的。 type singleton struct { //... } //private var instance *singleton //public func GetInstance() *singleton { if instance == nil { instance = &singleton{} } return instance } 带锁的单例模式 sync包提供两种锁类型:Mutex和RWMutex。Mutex是我们常见的锁类型,当一个goroutine获得Mutex之后,其它的goroutine只能进行等待直到该Mutex被释放。而RWMutex则是较为友好的单读多写模型,写锁会阻止其它所任何goroutine访问,而读锁则只会阻止写而不阻止读。 这里使用了Go的sync.Mutex,解决了懒汉模式的线程安全问题,但是在已生成实例后每次访问还都会调用锁,造成不必要的开销。 type singleton sturct { } var instance *singleton var mu sync.Mutex func GetInstance() *singleton { mu.Lock()

Golang通过Thrift框架完美实现跨语言调用

*爱你&永不变心* 提交于 2019-12-01 21:52:20
  每种语言都有自己最擅长的领域,Golang 最适合的领域就是服务器端程序。   做为服务器端程序,需要考虑性能同时也要考虑与各种语言之间方便的通讯。采用 http 协议简单,但性能不高。采用 TCP 通讯,则需要考虑封包、解包、粘包等等很多因素,而且想写个高效的 TCP 服务,也很难。   其实,对于此类需求,采用 RPC ( Remote Procedure Call Protocol ) 编程最靠谱。使用 RPC 编程 被认为是在分布式环境中运行的客户机和服务器应用程序之间进行可靠通信的最强大、最高效的方法之一。   Golang 内置了对 RPC 支持,但只能适用于 go 语言程序之间调用,且貌似序列化、反序列化性能不高。如果 go 语言能使用 Thrift 开发,那么就如虎添翼了。可惜, thrift 虽然很早就包含了 golang 的代码,但一直都存在各种问题无法正确执行,以至于GitHub上有许多大牛小牛自行实现的Thrift代码,但依然各种问题……直到 0.9.1 版本的发布!   是的,最近, Apache Thrift 0.9.1 正式发布了。新版的 Thrift 终于对 Golang 提供了完美的支持。经过实验,服务器端、客户端已经完美支持跨语言调用,且性能、尤其是内存占用上,编译型语言的特点展现出来,比 java 版的实现强了很多。   下面,我们采用

golang channel

 ̄綄美尐妖づ 提交于 2019-12-01 19:38:53
go channel 如果该通道已经关闭了 并尝试去获取该通道值不会造成恐慌 反之如果要往以关闭通道里添加数据则会发送恐慌 func main() { ch1 := make(chan int, 3) ch1 <- 2 ch1 <- 1 ch1 <- 3 go func() { for{ time.Sleep(time.Second) elem1 := <-ch1 //这里不会发生恐慌 fmt.Printf("The first element received from channel ch1: %v\n",elem1) } }() go func() { close(ch1) //直接关闭 }() time.Sleep(time.Second*10) } golang channel 有两种通道 make(chan type) //非缓冲区 make(chan type, size) //带有缓冲区 来源: https://www.cnblogs.com/jackey2015/p/11714964.html

Golang Channel原理解析

你。 提交于 2019-12-01 19:38:50
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 本文链接:https://blog.csdn.net/u010853261/article/details/85231944 本文主要分析golang实现并发基础组件channel的实现原理; 主要内容分为几个部分 Section1:channel使用实例分析 Section2:源码分析 Golang-Channel原理解析 Section1 channel使用实例 1.1 make channel 1.2 sends and receives 1.3 channel主要特性 Section2 源码分析 2.1 channel数据存储结构 2.2 make channel 2.3 协程从channel接收数据(goroutine receive data) 2.4 协程向channel写入数据(goroutine sender data) 2.5 channel close关闭channel源码分析 Section1 channel使用实例 channel主要是为了实现go的并发特性,用于并发通信的,也就是在不同的协程单元goroutine之间同步通信。 下面主要从三个方面来讲解: make channel,主要也就是hchan的数据结构原型; 发送和接收数据时

golang 切片使用注意事项

孤街浪徒 提交于 2019-12-01 18:51:22
// list 默认值为nil,可以直接append值,有值后json后为数组对象,但如果没有初始化空间的话,json编码后为null var list []*Pepole // list 初始化空间后为数组,json编码后为[] list = make([]*Pepole, 0) //故,不管是否有值,要转为json之前最好先初始化 示例: 为数组 为null js 判断区别 来源: https://www.cnblogs.com/BluePegasus/p/11713020.html

利用golang优雅的实现单实例

牧云@^-^@ 提交于 2019-12-01 17:38:51
平时编写代码过程中,经常会遇到对于全局角度只需运行一次的代码,比如全局初始化操作,设计模式中的单例模式。针对单例模式, java 中又出现了饿汉模式、懒汉模式,再配合 synchronized 同步关键字来实现。其目的无非就是将对象只初始化一次,而且最好保证在用到的时候再进行初始化,以避免初始化太早浪费资源,或者两次初始化破坏单例模式的实例唯一性。 Go 语言的 sync 包中提供了一个 Once 类型来保证全局的唯一性操作,其通过 Do(f func()) 方法来实现,即使 f 函数发生变化,其也不会被执行,下面我们来看一个小例子: package main import ( "fmt" "sync" "time" ) var once sync.Once func main() { //once循环调用firstMethod函数10次,其实只执行一次 for i := 0; i < 10; i++ { once.Do(firstMethod) fmt.Println("count:---", i) } //起10个协程,虽然用once去调secondMethod函数,但该函数不会被执行 //只打印------i for i := 0; i < 10; i++ { go func(i int) { once.Do(secondMethod) fmt.Println("-----"

golang初探与命令源码分析

耗尽温柔 提交于 2019-12-01 17:35:25
前段时间有群友在群里问一个go语言的问题: 就是有一个main.go的main函数里调用了另一个demo.go里的hello()函数。其中main.go和hello.go同属于main包。但是在main.go的目录下执行go run main.go却报hello函数没有定义的错: 代码结构如下: **gopath ---- src** **----gohello** **----hello.go** ** ----main.go** main.go如下: package main import "fmt" func main() { fmt.Println("my name is main") hello() } hello.go如下: package main import "fmt" func hello() { fmt.Println("my name is hello") } 当时我看了以为是他GOPATH配置的有问题,然后自己也按照这样试了一下,报同样的错,在网上查了,也有两篇文章是关于这个错的,也提供了解决方法,即用go run main.go hello.go,试了确实是可以的。 虽然是个很简单的问题,但是也涉及到了go语言底层对于命令行参数的解析。那就来分析一下语言底层的实现吧,看一下底层做了什么,为什么报这个错? 分析: 以下使用到的Go SDK版本为1.8.3

golang---常用函数

99封情书 提交于 2019-12-01 17:04:48
package main; import ( "os" "fmt" "time" "strings" ) //os包中的一些常用函数 func main() { //获取主机名 fmt.Println(os.Hostname()); //获取当前目录 fmt.Println(os.Getwd()); //获取用户ID fmt.Println(os.Getuid()); //获取有效用户ID fmt.Println(os.Geteuid()); //获取组ID fmt.Println(os.Getgid()); //获取有效组ID fmt.Println(os.Getegid()); //获取进程ID fmt.Println(os.Getpid()); //获取父进程ID fmt.Println(os.Getppid()); //获取环境变量的值 fmt.Println(os.Getenv("GOPATH")); //设置环境变量的值 os.Setenv("TEST", "test"); //改变当前工作目录 os.Chdir("C:/"); fmt.Println(os.Getwd()); //创建文件 f1, _ := os.Create("./1.txt"); defer f1.Close(); //修改文件权限 if err := os.Chmod("./1.txt",

Golang fmt Printf 格式化参数手册/详解/说明

本秂侑毒 提交于 2019-12-01 16:44:37
fmt 包实现了格式化I/O函数,类似于C的 printf 和 scanf. 格式“占位符”衍生自C,但比C更简单。 fmt 包的官方文档对Printing和Scanning有很详细的说明。这里就直接引用文档进行说明,同时附上额外的说明或例子,之后再介绍具体的函数使用。 以下例子中用到的类型或变量定义: type Website struct { Name string } // 定义结构体变量 var site = Website{Name:"studygolang"} 1.1. Printing 1.1.1. 占位符 普通占位符 占位符 说明 举例 输出 %v 相应值的默认格式。 Printf("%v", site),Printf("%+v", site) {studygolang},{Name:studygolang} 在打印结构体时,“加号”标记(%+v)会添加字段名 %#v 相应值的Go语法表示 Printf("#v", site) main.Website{Name:"studygolang"} %T 相应值的类型的Go语法表示 Printf("%T", site) main.Website %% 字面上的百分号,并非值的占位符 Printf("%%") % 布尔占位符 占位符 说明 举例 输出 %t 单词 true 或 false。 Printf("%t", true