golang 插入redis 集合,并判断元素是否存在

李魔佛 发表了文章 • 0 个评论 • 87 次浏览 • 2022-06-20 17:26 • 来自相关话题

代码如下:
1. "server/service" 是当前的报名
2. 用的go-redis这个库
 
判断元素是否在集合中:

conn.SIsMember("User", sign).Result()

完整代码:
package cache

import (
"server/service"
"fmt"
"github.com/go-redis/redis"
)

type Cache struct {
conn *redis.Client
}

func (this *Cache) CacheInit() {
this.connect()

}
func (this *Cache) connect() {
conf := service.ReadRedisConfig()
this.conn = redis.NewClient(&redis.Options{
Addr: conf.Addr,
Password: conf.Password,
DB: conf.DB,
})

}
func (this *Cache) Get(id string) (string, bool) {
result, err := this.conn.Get(id).Result()
if err != nil {
fmt.Println(err)
return "", false
}
return result, true
}

func (this *Cache) Set(id string, content string) bool {
_, err := this.conn.Set(id, content, 0).Result()
if err != nil {
fmt.Println(err)
return false
} else {
return true
}
}

func (this *Cache) CheckUserExist(sign string) bool {
result, err := this.conn.SIsMember("User", sign).Result()
if err != nil {
fmt.Println(err)
return false
}
return result
}

func (this *Cache) AddUser(name string) bool {
_, err := this.conn.SAdd("User", name).Result()
if err != nil {
fmt.Println(err)
return false
} else {
return true
}

}

github地址:
https://github.com/Rockyzsu/BondInfoServer.git
  查看全部
代码如下:
1. "server/service" 是当前的报名
2. 用的go-redis这个库
 
判断元素是否在集合中:

conn.SIsMember("User", sign).Result()

完整代码:
package cache

import (
"server/service"
"fmt"
"github.com/go-redis/redis"
)

type Cache struct {
conn *redis.Client
}

func (this *Cache) CacheInit() {
this.connect()

}
func (this *Cache) connect() {
conf := service.ReadRedisConfig()
this.conn = redis.NewClient(&redis.Options{
Addr: conf.Addr,
Password: conf.Password,
DB: conf.DB,
})

}
func (this *Cache) Get(id string) (string, bool) {
result, err := this.conn.Get(id).Result()
if err != nil {
fmt.Println(err)
return "", false
}
return result, true
}

func (this *Cache) Set(id string, content string) bool {
_, err := this.conn.Set(id, content, 0).Result()
if err != nil {
fmt.Println(err)
return false
} else {
return true
}
}

func (this *Cache) CheckUserExist(sign string) bool {
result, err := this.conn.SIsMember("User", sign).Result()
if err != nil {
fmt.Println(err)
return false
}
return result
}

func (this *Cache) AddUser(name string) bool {
_, err := this.conn.SAdd("User", name).Result()
if err != nil {
fmt.Println(err)
return false
} else {
return true
}

}

github地址:
https://github.com/Rockyzsu/BondInfoServer.git
 

在中国网络环境下获取Golang.org上的Golang Packages

李魔佛 发表了文章 • 0 个评论 • 116 次浏览 • 2022-06-16 10:26 • 来自相关话题

在中国网络环境下获取Golang.org上的Golang Packages

背景
目前在中国网络环境下无法访问Golang.org。
问题
不能运行go get golang.org/x/XX来获取Golang packages。

解决方案
方案 A: 使用github 上的镜像

获取Golang Package在github镜像上的路径: golang.org/x/PATH_TO_PACKAGE --> github.com/golang/PATH_TO_PACKAGE.

// Ex:
golang.org/x/net/context --> github.com/golang/net/context
运行go get来安装github镜像的Golang packages。

// Ex:
go get github.com/golang/net/context
你会碰到如下错误提示:

package github.com/golang/net/context:
code in directory /go/src/github.com/golang/net/context
expects import "golang.org/x/net/context"
忽略错误。 Golang的Package的源代码已经成功下载于:
$GOPATH/src/github.com/golang/PATH_TO_PACKAGE.

复制 $GOPATH/src/github.com/golang/PATH_TO_PACKAGE 到 $GOPATH/src/golang.org/x/PATH_TO_PACKAGE.

// Ex:
mkdir $GOPATH/src/golang.org/x -p
cp $GOPATH/src/github.com/golang/net $GOPATH/src/golang.org/x/ -rf
运行 go build 来编译。

方案 B: 使用第三方网站 - https://gopm.io/download

输入包路径即可下载zip文件。 查看全部
在中国网络环境下获取Golang.org上的Golang Packages

背景
目前在中国网络环境下无法访问Golang.org。
问题
不能运行go get golang.org/x/XX来获取Golang packages。

解决方案
方案 A: 使用github 上的镜像

获取Golang Package在github镜像上的路径: golang.org/x/PATH_TO_PACKAGE --> github.com/golang/PATH_TO_PACKAGE.

// Ex:
golang.org/x/net/context --> github.com/golang/net/context
运行go get来安装github镜像的Golang packages。

// Ex:
go get github.com/golang/net/context
你会碰到如下错误提示:

package github.com/golang/net/context:
code in directory /go/src/github.com/golang/net/context
expects import "golang.org/x/net/context"
忽略错误。 Golang的Package的源代码已经成功下载于:
$GOPATH/src/github.com/golang/PATH_TO_PACKAGE.

复制 $GOPATH/src/github.com/golang/PATH_TO_PACKAGE 到 $GOPATH/src/golang.org/x/PATH_TO_PACKAGE.

// Ex:
mkdir $GOPATH/src/golang.org/x -p
cp $GOPATH/src/github.com/golang/net $GOPATH/src/golang.org/x/ -rf
运行 go build 来编译。

方案 B: 使用第三方网站 - https://gopm.io/download

输入包路径即可下载zip文件。

golang gin ajax post 前端与后端的正确写法

李魔佛 发表了文章 • 0 个评论 • 147 次浏览 • 2022-06-08 18:42 • 来自相关话题

比较常用的场景,记录一下:
前端是一个页面html页面
<script type="text/javascript">
var submitBTN = document.getElementById("url_update");
submitBTN.onclick = function (event) {
// 注意这里是 onclick 函数
console.log("click");
$.ajax({
url: "/update-site1",
type: "POST",
data: {value:1},
cache: false,
contentType: "application/x-www-form-urlencoded",
success: function (data) {
console.log(data);

if (data.code !== 0) {
alert('更新失败')
} else {
new_str = data.res + " " + data.count
$("#txt_content").val(new_str);
alert('更新资源成功!')
}
},
fail: function (data) {
alert("更新失败!");
}
});

$.ajax({
url: "/update-site1",
type: "POST",
data: {value:2},
cache: false,
contentType: "application/x-www-form-urlencoded",
success: function (data) {
console.log(data);

if (data.code !== 0) {
alert('更新失败')
} else {
new_str = data.res + " " + data.count
$("#txt_content").val(new_str);
alert('更新资源成功!')
}
},
fail: function (data) {
alert("更新失败!");
}
})

}

</script>
效果大体上这样的:





 
有几个按钮,然后每个按钮绑定一个点击事件
 
submitBTN.onclick = function (event) {
.....
同上面代码
 
然后在代码里面执行post操作,使用的是ajax封装的方法:
 
注意,contentType用下面的:
contentType: "application/x-www-form-urlencoded",
还有不要把
processData: false,这个设置为false,否则gin的后端解析不到数据
 
写完前端之后,就去后端
 
路由方法:
绑定上面的url update-site1
router.POST("/update-site1", controllers.BaiduSite1)
 然后就是实现
controllers.BaiduSite1 这个方法:
 
func BaiduSite1(ctx *gin.Context) {
if ctx.Request.Method == "POST" {

value := ctx.PostForm("value")
fmt.Println(value)
int_value, err := strconv.Atoi(value)
if err != nil {
ctx.JSON(http.StatusOK, gin.H{
"code": 1,
"res": "",
"count": 0,
})
return
}
res, count := webmaster.PushProcess(1, int_value)
ctx.JSON(http.StatusOK, gin.H{
"code": 0,
"res": res,
"count": count,
})
}
}
 获取ajax里面的字段,
使用:context 中的PostForm方法
value := ctx.PostForm("value")
 剩下的就是一些常规的操作方法

最后需要设置json的返回数据
ctx.JSON(http.StatusOK, gin.H{
"code": 0,
"res": res,
"count": count,

 完整代码可以到公众号里面获取:
 


 
  查看全部
比较常用的场景,记录一下:
前端是一个页面html页面
<script type="text/javascript">
var submitBTN = document.getElementById("url_update");
submitBTN.onclick = function (event) {
// 注意这里是 onclick 函数
console.log("click");
$.ajax({
url: "/update-site1",
type: "POST",
data: {value:1},
cache: false,
contentType: "application/x-www-form-urlencoded",
success: function (data) {
console.log(data);

if (data.code !== 0) {
alert('更新失败')
} else {
new_str = data.res + " " + data.count
$("#txt_content").val(new_str);
alert('更新资源成功!')
}
},
fail: function (data) {
alert("更新失败!");
}
});

$.ajax({
url: "/update-site1",
type: "POST",
data: {value:2},
cache: false,
contentType: "application/x-www-form-urlencoded",
success: function (data) {
console.log(data);

if (data.code !== 0) {
alert('更新失败')
} else {
new_str = data.res + " " + data.count
$("#txt_content").val(new_str);
alert('更新资源成功!')
}
},
fail: function (data) {
alert("更新失败!");
}
})

}

</script>

效果大体上这样的:

20220608004.jpg

 
有几个按钮,然后每个按钮绑定一个点击事件
 
submitBTN.onclick = function (event) {
.....
同上面代码
 
然后在代码里面执行post操作,使用的是ajax封装的方法:
 
注意,contentType用下面的:
contentType: "application/x-www-form-urlencoded",

还有不要把
processData: false,
这个设置为false,否则gin的后端解析不到数据
 
写完前端之后,就去后端
 
路由方法:
绑定上面的url update-site1
	router.POST("/update-site1", controllers.BaiduSite1)

 然后就是实现
controllers.BaiduSite1 这个方法:
 
func BaiduSite1(ctx *gin.Context) {
if ctx.Request.Method == "POST" {

value := ctx.PostForm("value")
fmt.Println(value)
int_value, err := strconv.Atoi(value)
if err != nil {
ctx.JSON(http.StatusOK, gin.H{
"code": 1,
"res": "",
"count": 0,
})
return
}
res, count := webmaster.PushProcess(1, int_value)
ctx.JSON(http.StatusOK, gin.H{
"code": 0,
"res": res,
"count": count,
})
}
}

 获取ajax里面的字段,
使用:context 中的PostForm方法
value := ctx.PostForm("value")

 剩下的就是一些常规的操作方法

最后需要设置json的返回数据
ctx.JSON(http.StatusOK, gin.H{
"code": 0,
"res": res,
"count": count,

 完整代码可以到公众号里面获取:
 


 
 

docker部署golang应用 无法下载第三方包 解决办法

李魔佛 发表了文章 • 0 个评论 • 326 次浏览 • 2022-03-14 14:43 • 来自相关话题

需要把docker内部的环境改一下其GOPROXY地址就可以了。 
ENV GOPROXY https://goproxy.cn
RUN go mod download
RUN go build main.go
 
需要把docker内部的环境改一下其GOPROXY地址就可以了。 
ENV GOPROXY https://goproxy.cn
RUN go mod download
RUN go build main.go

 

性能测试: flask WSGI vs 异步 ASGI vs tornodo vs Golang Gin

李魔佛 发表了文章 • 0 个评论 • 1010 次浏览 • 2022-01-12 10:58 • 来自相关话题

做一个基本的性能基准测试。测试脚本使用是apach benchmark
测试命令:
ab -kc 1000 -n 4000 http://127.0.0.1:5000/
 

代码最精简:
flask wsgi:from flask import Flask

app = Flask(__name__)

@app.route('/')
def hello_world():
return 'Hello, World!'

if __name__ == '__main__':
app.run(host='0.0.0.0')
得到的结果:
 

ASGI的代码:async def app(scope, receive, send):
await send({
'type': 'http.response.start',
'status': 200,
'headers': [
[b'content-type', b'text/html']
]
})

await send({
'type': 'http.response.body',
'body': b'Hello This is server running',
'more_body': False
}) 
运行命令:
uvicorn --host 0.0.0.0 simple_asgi:app
 
得到的结果:

 
 
python的tornado
from tornado import ioloop
from tornado import web
class Homepage(web.RequestHandler):

def get(self):
print('get method')
self.write("This is tornado server")

if __name__ == '__main__':
app = web.Application([
("/",Homepage),

])

app.listen(8888)
ioloop.IOLoop.current().start()
 
 
Goland的gin package main

import "github.com/gin-gonic/gin"

// 测试专用

func main() {
r := gin.Default()
r.GET("/index", func(c *gin.Context) {
c.JSON(200, gin.H{"message": "Working"})
})
r.GET("/", func(c *gin.Context) {
c.JSON(200, gin.H{"message": "Working"})
})
r.Run()
}

 
通过requests per second 每秒的请求数:
flask : 1000
uvicorn: 2000
tornoda:3000
go gin:4000

 
所以综合测试结果,flask的性能最烂,go gin的性能最好。差了4倍。
 
转载请注明出处:
http://www.30daydo.com/article/44336
  查看全部
做一个基本的性能基准测试。测试脚本使用是apach benchmark
测试命令:
ab -kc 1000 -n 4000 http://127.0.0.1:5000/
 

代码最精简:
flask wsgi:
from flask import Flask

app = Flask(__name__)

@app.route('/')
def hello_world():
return 'Hello, World!'

if __name__ == '__main__':
app.run(host='0.0.0.0')

得到的结果:
 

ASGI的代码:
async def app(scope, receive, send):
await send({
'type': 'http.response.start',
'status': 200,
'headers': [
[b'content-type', b'text/html']
]
})

await send({
'type': 'http.response.body',
'body': b'Hello This is server running',
'more_body': False
})
 
运行命令:
uvicorn --host 0.0.0.0 simple_asgi:app
 
得到的结果:

 
 
python的tornado
from tornado import  ioloop
from tornado import web
class Homepage(web.RequestHandler):

def get(self):
print('get method')
self.write("This is tornado server")

if __name__ == '__main__':
app = web.Application([
("/",Homepage),

])

app.listen(8888)
ioloop.IOLoop.current().start()

 
 
Goland的gin
 package main

import "github.com/gin-gonic/gin"

// 测试专用

func main() {
r := gin.Default()
r.GET("/index", func(c *gin.Context) {
c.JSON(200, gin.H{"message": "Working"})
})
r.GET("/", func(c *gin.Context) {
c.JSON(200, gin.H{"message": "Working"})
})
r.Run()
}


 
通过requests per second 每秒的请求数:
flask : 1000
uvicorn: 2000
tornoda:3000
go gin:4000

 
所以综合测试结果,flask的性能最烂,go gin的性能最好。差了4倍。
 
转载请注明出处:
http://www.30daydo.com/article/44336
 

ubuntu goland破解激活教程

李魔佛 发表了文章 • 0 个评论 • 1242 次浏览 • 2022-01-05 13:08 • 来自相关话题

很大小伙伴是使用ubuntu作为主力开发机的。
ubuntu下的goland可以直接到官网下载。
或者在自带的software center。
 
不过goland只能试用一个月,一个月后只能要激活。
 
所以有一个reset插件,可以每次开启goland的时候把激活日期重置,往后推一个月。
 
只需要打开goland,然后把插件拖进去goland的界面即可。

 

 


 
插件获取方式:
关注公众号:
 
30天尝试新事情

 
 
后台回复:goland激活
即可 查看全部
很大小伙伴是使用ubuntu作为主力开发机的。
ubuntu下的goland可以直接到官网下载。
或者在自带的software center。
 
不过goland只能试用一个月,一个月后只能要激活。
 
所以有一个reset插件,可以每次开启goland的时候把激活日期重置,往后推一个月。
 
只需要打开goland,然后把插件拖进去goland的界面即可。

 

 


 
插件获取方式:
关注公众号:
 
30天尝试新事情

 
 
后台回复:goland激活
即可

ubuntu(centos)下golang下载libxml2 报错信息, go 安装libxml2

李魔佛 发表了文章 • 0 个评论 • 506 次浏览 • 2021-12-29 23:20 • 来自相关话题

ubuntu下golang下载libxml2 报错信息:$ go get -u github.com/lestrrat-go/libxml2
# pkg-config --cflags -- libxml-2.0 Package libxml-2.0 was not found in the pkg-config search path.
Perhaps you should add the directory containing `libxml-2.0.pc' to the PKG_CONFIG_PATH environment variable
No package 'libxml-2.0' found pkg-config: exit status 1 ​ ​
 
因为系统少了个libxml2 开发包:

使用以下命令即可修复:sudo apt install libxml2-dev 
 
如果是centos的话,安装命令:yum install libxml2
yum install libxml2-devel
注意是 libxml2-devel !
别用那种下载源码编译的方法,能用yum就用yum,否则弄得系统一堆依赖问题。 查看全部
ubuntu下golang下载libxml2 报错信息:
$ go get -u github.com/lestrrat-go/libxml2                     
# pkg-config --cflags -- libxml-2.0 Package libxml-2.0 was not found in the pkg-config search path.
Perhaps you should add the directory containing `libxml-2.0.pc' to the PKG_CONFIG_PATH environment variable
No package 'libxml-2.0' found pkg-config: exit status 1 ​ ​

 
因为系统少了个libxml2 开发包:

使用以下命令即可修复:
sudo apt install libxml2-dev
 
 
如果是centos的话,安装命令:
yum install libxml2
yum install libxml2-devel

注意是 libxml2-devel !
别用那种下载源码编译的方法,能用yum就用yum,否则弄得系统一堆依赖问题。

现在很多公众号都是粗制滥造, 代码也没经过验证 就贴上来害人

李魔佛 发表了文章 • 0 个评论 • 477 次浏览 • 2021-12-27 11:52 • 来自相关话题

来看看这个公众号 :  Golang来啦
 

 
你说函数签名的Counter写错就算了. 但是返回的也是一个指针呀......
 
正确写法
func NewNotSafeCounter() *NotSafeCounter {
return &NotSafeCounter{0}
}
 
  查看全部
来看看这个公众号 :  Golang来啦
 

 
你说函数签名的Counter写错就算了. 但是返回的也是一个指针呀......
 
正确写法
func NewNotSafeCounter() *NotSafeCounter {
return &NotSafeCounter{0}
}

 
 

golang json Unmarshal 无法修改结构体的值。传入指针

李魔佛 发表了文章 • 0 个评论 • 601 次浏览 • 2021-12-20 12:59 • 来自相关话题

假如我的json文件的格式如下:
 { "username": "root", "password": "123456", "host": "1.1.1.1.", "port": 3306, "db": "admin" }

然后我的定义的结构体:
 
type T struct {

username string `json:"username"`
password string `json:"password"`
host string `json:"host"`
port int `json:"port"`
db string `json:"db"`

}

然后程序里面解析json的代码:var t T
data, err := ioutil.ReadFile(filename)
fmt.Println("read from file")
//fmt.Println(string(data))
if err != nil {
fmt.Println("in error")
fmt.Println(err)
return err
}
err = json.Unmarshal(data, &t)
if err != nil {
fmt.Println("error ")
fmt.Println(err)
return err
}
fmt.Println("outpout ")
fmt.Printf("%v\n", t)
fmt.Println(t)
发现是无法把t的值修改为json文件里面的值,最后的记过输出,还是一个零值的结果体。

后面知道问题所在了,如果定义的结构体的首字母小写的时候,包外的反射是无法修改结构体的值的,也就是只能只读。

所以只需要把结构体的首字母改为大写,问题就可以解决了。type T struct {
Username string `json:"username"`
Password string `json:"password"`
Host string `json:"host"`
Port int `json:"port"`
Db string `json:"db"`
}
json文件里面不用修改,因为
Unmarshal映射的时候可以适配大小写。
  查看全部
假如我的json文件的格式如下:
 
{ "username": "root", "password": "123456", "host": "1.1.1.1.", "port": 3306, "db": "admin" }

然后我的定义的结构体:
 
type T struct { 

username string `json:"username"`
password string `json:"password"`
host string `json:"host"`
port int `json:"port"`
db string `json:"db"`

}


然后程序里面解析json的代码:
var t T
data, err := ioutil.ReadFile(filename)
fmt.Println("read from file")
//fmt.Println(string(data))
if err != nil {
fmt.Println("in error")
fmt.Println(err)
return err
}
err = json.Unmarshal(data, &t)
if err != nil {
fmt.Println("error ")
fmt.Println(err)
return err
}
fmt.Println("outpout ")
fmt.Printf("%v\n", t)
fmt.Println(t)

发现是无法把t的值修改为json文件里面的值,最后的记过输出,还是一个零值的结果体。

后面知道问题所在了,如果定义的结构体的首字母小写的时候,包外的反射是无法修改结构体的值的,也就是只能只读。

所以只需要把结构体的首字母改为大写,问题就可以解决了。
type T struct {
Username string `json:"username"`
Password string `json:"password"`
Host string `json:"host"`
Port int `json:"port"`
Db string `json:"db"`
}

json文件里面不用修改,因为
Unmarshal映射的时候可以适配大小写。
 

为什么现在还有那么多在线的gonlang 字符串生成json struct的网站? Goland IDE一个快捷方式帮你搞定

李魔佛 发表了文章 • 0 个评论 • 439 次浏览 • 2021-12-20 01:00 • 来自相关话题

在golanad的ide上,敲入 type xx struct{
}
 
在出现的generate from json的页面,把json的字符串输入进去。
 
IDE即可帮你转换为对应的结构体了。 根本就没有在线IDE什么事情了。
在golanad的ide上,敲入 type xx struct{
}
 
在出现的generate from json的页面,把json的字符串输入进去。
 
IDE即可帮你转换为对应的结构体了。 根本就没有在线IDE什么事情了。

golang根据不同返回解析不同结构的json

李魔佛 发表了文章 • 0 个评论 • 506 次浏览 • 2021-12-20 00:35 • 来自相关话题

// 数据源
{"type":"a_number", "data":{"somenumber":1234}}
{"type":"b_string", "data":{"somestring":"a string", "anotherstring": "a second string"}}` 
如何解析上面返回的json结构体
 
答:json.RawMessage
 
type Head struct {
Type string `json:"type"`
Data json.RawMessage `json:"data"`
}


var msg Head

json.Unmarshal([]byte(jsonString), &msg)

switch msg.Type {
case "a_number":
var detail A
json.Unmarshal([]byte(msg.Data),&detail)
fmt.Println(detail.SomeNumber)
case "b_string":
var detail B
json.Unmarshal([]byte(msg.Data),&detail)
fmt.Println(detail.SomeString)
default:
fmt.Printf("I don't know about type %s!\n", msg.Type)
}
 
就可以解析上面的不规则的结构体了。
 
  查看全部
// 数据源
{"type":"a_number", "data":{"somenumber":1234}}
{"type":"b_string", "data":{"somestring":"a string", "anotherstring": "a second string"}}`
 
如何解析上面返回的json结构体
 
答:json.RawMessage
 
type Head struct {
Type string `json:"type"`
Data json.RawMessage `json:"data"`
}


var msg Head

json.Unmarshal([]byte(jsonString), &msg)

switch msg.Type {
case "a_number":
var detail A
json.Unmarshal([]byte(msg.Data),&detail)
fmt.Println(detail.SomeNumber)
case "b_string":
var detail B
json.Unmarshal([]byte(msg.Data),&detail)
fmt.Println(detail.SomeString)
default:
fmt.Printf("I don't know about type %s!\n", msg.Type)
}

 
就可以解析上面的不规则的结构体了。
 
 

Go 测试题1

李魔佛 发表了文章 • 0 个评论 • 468 次浏览 • 2021-12-15 12:32 • 来自相关话题

问一个基础
func main() {
v := [...]int{1: 2, 3: 4}
fmt.Println( len(v))
}

这个为什么长度是 4?
 
 
答案:
v数组分配内存[0,2,0,4],所以长度为4。 查看全部
问一个基础
func main() {
v := [...]int{1: 2, 3: 4}
fmt.Println( len(v))
}

这个为什么长度是 4?
 
 
答案:
v数组分配内存[0,2,0,4],所以长度为4。

30天学会Golang

我是一个新兵 发表了文章 • 0 个评论 • 513 次浏览 • 2021-12-04 12:20 • 来自相关话题

适合有一定的编程基础的同学学习。
附github目录图以及github地址
 
https://github.com/Rockyzsu/GolangLearning
 



 同时欢迎关注公众号: 30天尝试新事情

 
  查看全部
适合有一定的编程基础的同学学习。
附github目录图以及github地址
 
https://github.com/Rockyzsu/GolangLearning
 



 同时欢迎关注公众号: 30天尝试新事情

 
 

golang 的sync.Cond Wait 为什么要先Lock之后才能Wait ?

李魔佛 发表了文章 • 0 个评论 • 565 次浏览 • 2021-11-24 00:09 • 来自相关话题

正确代码: func clickEvent(con *sync.Cond, fn HandleFun, id int) {
fmt.Println("waiting on broadcast")

fmt.Printf("Lock %d\n", id)
con.L.Lock() //需要现先lock
con.Wait()
fn()
defer con.L.Unlock()
}
如果直接Wait,会报错,死锁
 
然后看了看源码:





 
原来Wait函数里面,会先Unlock一次,再去跑runtime通知。
也就是你不Lock一下,进入到Wait函数就会一直锁住。
 
  查看全部
正确代码:
   func clickEvent(con *sync.Cond, fn HandleFun, id int) {        
fmt.Println("waiting on broadcast")

fmt.Printf("Lock %d\n", id)
con.L.Lock() //需要现先lock
con.Wait()
fn()
defer con.L.Unlock()
}

如果直接Wait,会报错,死锁
 
然后看了看源码:

Screenshot_2021-11-24_00-08-04.png

 
原来Wait函数里面,会先Unlock一次,再去跑runtime通知。
也就是你不Lock一下,进入到Wait函数就会一直锁住。
 
 

cannot install, GOBIN must be an absolute path

李魔佛 发表了文章 • 0 个评论 • 724 次浏览 • 2021-11-22 22:32 • 来自相关话题

原因是因为你的系统环境变量用的相对路径 %GOPATH%/bin
 
把GOPATH替换为完整的路径,比如C:\User\Admin\go\bin 即可解决问题。
原创文章,转载请注明出处: 
http://30daydo.com/article/44290
  查看全部
原因是因为你的系统环境变量用的相对路径 %GOPATH%/bin
 
把GOPATH替换为完整的路径,比如C:\User\Admin\go\bin 即可解决问题。
原创文章,转载请注明出处: 
http://30daydo.com/article/44290