golang 代码笔记
锁
互斥锁,g0获取锁,到释放锁之间,g1去获取锁失败,阻塞,g0释放锁之后g1获取锁成功,gn阻塞。
package main
import (
"fmt"
"sync"
"time"
)
func main() {
//声明
var mutex sync.Mutex
fmt.Println("Lock the lock. (G0)")
//加锁mutex
mutex.Lock()
fmt.Println("The lock is locked.(G0)")
for i := 1; i < 4; i++ {
go func(i int) {
fmt.Printf("Lock the lock. (G%d)\n", i)
mutex.Lock()
fmt.Printf("The lock is locked. (G%d)\n", i)
}(i)
}
//休息一会,等待打印结果
time.Sleep(time.Second)
fmt.Println("Unlock the lock. (G0)")
//解锁mutex
mutex.Unlock()
fmt.Println("The lock is unlocked. (G0)")
//休息一会,等待打印结果
time.Sleep(time.Second)
}
原子操作
通过atomic的AddUint32方法,只有一个协程可以操作sum,保证结果一定是150,原子操作相当于给sum加了锁。
package main
import (
"fmt"
"sync"
"sync/atomic"
)
var m *sync.Mutex
func main() {
var sum uint32 = 100
var wg sync.WaitGroup
for i := 0; i < 50; i++ {
wg.Add(1)
go func() {
defer wg.Done()
//sum += 1 //1
atomic.AddUint32(&sum, 1) //2
}()
}
wg.Wait()
fmt.Println(sum)
}
go的“any”类型
类似ts的any,但是很麻烦的是用这个字段的时候需要强转,就是.([]string)这个操作,如果range的时候没把内容转成字符串,就会报错,因为毕竟他是interface{}类型
package main
import (
"fmt"
)
func main() {
m := map[string]interface{}{
"Name": "Wednesday",
"Age": 6,
"Parents": []string{
"Gomez",
"Morticia",
},
}
maps := []interface{}{
"Gomez",
"Morticia",
}
fmt.Println(maps, m)
for key, value := range m["Parents"].([]string) {
fmt.Println("Key:", key, "Value:", value)
}
}
channel
go的chan关键字可以创建一个channel用于协程通信, ch <- 是写数据,<- ch是读数据,你也可以用range来读数据,当读不到数据的时候就会阻塞。所以下面的代码不写sleep,go进程也不会退出。
import (
"fmt"
// "time"
)
func main() {
var ch = make(chan []int)
num := []int{1, 2, 3}
i := 0
go func() {
for {
ch <- num
num = append(num, i)
i++
fmt.Println("write")
}
}()
for nu := range ch {
fmt.Println(nu)
}
}
channel一般都用select来消费,只要一个case成功就完成,不然就阻塞到成功。
package main
import (
"time"
"fmt"
)
func main(){
c := make(chan int)
select{
case <- c:
fmt.Println("没有数据")
case <-time.After(5* time.Second):
fmt.Println("超时退出")
}
}
利用多核cpu
通过设置runtime.GOMAXPROCS(2),让go协程可以跑在两个cpu上,所以打印的2次0-100,没有先后顺序。go的多核利用是利用多个cpu上跑协程。
并不是多核一定高效,比如io操作,单核比多核更快,单核没有线程切换的损耗,而且io操作并不需要go来做啥。多核的场景应该是高计算的任务。
import (
"fmt"
"runtime"
)
var quit chan int = make(chan int)
func loop() {
for i := 0; i < 100; i++ { //为了观察,跑多些
fmt.Printf("%d ", i)
}
quit <- 0
}
func main() {
runtime.GOMAXPROCS(2) // 最多使用2个核
go loop()
go loop()
for i := 0; i < 2; i++ {
<-quit
}
}
golang 代码笔记的更多相关文章
- golang学习笔记19 用Golang实现以太坊代币转账
golang学习笔记19 用Golang实现以太坊代币转账 在以太坊区块链中,我们称代币为Token,是以太坊区块链中每个人都可以任意发行的数字资产.并且它必须是遵循erc20标准的,至于erc20标 ...
- golang学习笔记8 beego参数配置 打包linux命令
golang学习笔记8 beego参数配置 打包linux命令 参数配置 - beego: 简约 & 强大并存的 Go 应用框架https://beego.me/docs/mvc/contro ...
- golang学习笔记7 使用beego swagger 实现API自动化文档
golang学习笔记7 使用beego swagger 实现API自动化文档 API 自动化文档 - beego: 简约 & 强大并存的 Go 应用框架https://beego.me/doc ...
- golang学习笔记6 beego项目路由设置
golang学习笔记5 beego项目路由设置 前面我们已经创建了 beego 项目,而且我们也看到它已经运行起来了,那么是如何运行起来的呢?让我们从入口文件先分析起来吧: package main ...
- golang学习笔记5 用bee工具创建项目 bee工具简介
golang学习笔记5 用bee工具创建项目 bee工具简介 Bee 工具的使用 - beego: 简约 & 强大并存的 Go 应用框架https://beego.me/docs/instal ...
- go语言,golang学习笔记4 用beego跑一个web应用
go语言,golang学习笔记4 用beego跑一个web应用 首页 - beego: 简约 & 强大并存的 Go 应用框架https://beego.me/ 更新的命令是加个 -u 参数,g ...
- go语言,golang学习笔记2 web框架选择
go语言,golang学习笔记2 web框架选择 用什么go web框架比较好呢?能不能推荐个中文资料多的web框架呢? beego框架用的人最多,中文资料最多 首页 - beego: 简约 & ...
- go语言,golang学习笔记1 官网下载安装,中文社区,开发工具LiteIDE
go语言,golang学习笔记1 官网下载安装,中文社区,开发工具LiteIDE Go语言是谷歌2009发布的专门针对多处理器系统应用程序的编程进行了优化,使用Go编译的程序可以媲美C或C++代码的速 ...
- TCP粘"包"问题浅析及解决方案Golang代码实现
一.粘"包"问题简介 在socket网络编程中,都是端到端通信,客户端端口+客户端IP+服务端端口+服务端IP+传输协议就组成一个可以唯一可以明确的标识一条连接.在TCP的sock ...
随机推荐
- 执行C#动态代码
执行C#动态代码 using System; using System.Data; using System.Configuration; using System.Text; using Syste ...
- jQuery中 对标签元素操作(2)
一.属性操作 1.获取属性和设置属性 例如下jQuery代码: var $para=$("p"); //获取<p>节点 var p_txt=$par ...
- springboot项目屏蔽mq或者mongodb的监控日志输出
最近写项目,用的是springboot,其中用到了rabbitmq和mongodb,配置完成 项目启动后,会输出如下日志: mongodb和mq的检测,会一直打印日志,这样会影响开发人员的测试. 如何 ...
- vue 组件开发、vue自动化工具、axios使用与router的使用(3)
一. 组件化开发 1.1 组件[component] 在网页中实现一个功能,需要使用html定义功能的内容结构,使用css声明功能的外观样式,还要使用js定义功能的特效,因此就产生了一个功能先关的代码 ...
- php使用root用户启动
一般情况下,肯定是不推荐使用root用户启动php的 但是在某些服务器管理想使用WEB的方式来控制操作的话,那么就必须要使用root用户才有权限操作 1.修改配置文件php-fpm.conf的启动用户 ...
- jdk 环境变量
1. jdk安装后的目录 2.JAVA_HOME C:\Program Files\Java\jdk1.8.0_172 3.PATH %JAVA_HOME%\bin 4.CLASSPATH .;%JA ...
- 重建二叉树[by Python]
题目: 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.假设输入的前序遍历和中序遍历的结果中都不含重复的数字.例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2 ...
- [LeetCode] 6. Z 字形变换
题目链接:(https://leetcode-cn.com/problems/zigzag-conversion/) 题目描述: 将一个给定字符串根据给定的行数,以从上往下.从左到右进行 Z 字形排列 ...
- 将List按照指定大小等分的几种实现方式和效率对比及优化
今天碰到一个需求,定时任务,批量从表里取数据并做一些其他操作然后再存表,每次取1000条,由于计算过程比较耗时所以要起多个线程同时跑,需要将List按照指定大小等分,如每100条数据起一个线程,若最后 ...
- sigsuspend()阻塞:异步信号SIGIO为什么会被截胡?
关键词:fcntl.fasync.signal.sigsuspend.pthread_sigmask.trace events. 此文主要是解决问题过程中的记录,内容有较多冗余.但也反映解决问题中用到 ...